【问题标题】:Why dose many MVC html Helpers uses Delegates as input parameters为什么许多 MVC html Helpers 使用 Delegates 作为输入参数
【发布时间】:2013-03-22 06:52:14
【问题描述】:

在 MVC 中,如果您想为属性创建编辑器或为您的属性创建显示,您可以执行以下操作:

@Html.EditorFor(m=> m.MyModelsProperty);
@Html.DisplayFor(m=> m.MyModlesProperty);

为什么我们必须传递一个委托为什么我们不能直接传递模型的属性?例如:

@html.EditorFor(Model.MyModlesProperty);

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 delegates html-helper mvc-editor-templates


    【解决方案1】:

    这是因为元数据。您知道,您可以在模型上添加的所有属性,例如[Required][DisplayName][DisplayFormat],......所有这些属性都是从 lambda 表达式中提取的。如果您只是传递一个值,那么助手将无法从中提取任何元数据。这只是一个虚拟值。

    lambda 表达式允许分析模型上的属性并从中读取元数据。然后助手变得智能,并根据您指定的属性采取不同的行动。

    因此,通过使用 lambda 表达式,助手可以做更多的事情,而不仅仅是显示一些值。它能够格式化这个值,它能够验证这个值,...

    【讨论】:

      【解决方案2】:

      我想补充一点,除了 Metadata 和将 Html 助手强类型化为 Model 类型之外,还有另一个原因:

      表达式允许您知道属性的名称,而无需将字符串硬编码到项目中。如果您检查 MVC 生成的 HTML,您会看到您的输入字段被命名为 "ModelType_PropertyName",然后允许 Model Binder 创建复杂类型,并传递给您的控制器操作,如下所示:

      public ActionResult Foo(MyModel model) { ... }
      

      另一个原因是Linq to SQL。表达式树是将 Lambda 转换为 SQL 查询所必需的魔法。 因此,如果您要执行以下操作:

      Html.DisplayFor(p => p.Addresses.Where(j => j.Country == "USA"))
      

      并且您的 DbContext 仍处于打开状态,它将执行查询。

      更新
      划出了一个错误。你每天都会学到新东西。

      【讨论】:

      • So if you were to do something like: Html.DisplayFor(p => p.Addresses.Where(j => j.Country == "USA")) - 你不能这样做。仅支持简单表达式(属性和索引器访问)。这将失败并出现错误。
      • @DarinDimitrov 嗯.. 你是对的。但为什么?如果它必须显示我的IList<Address> 或我刚刚从中查询出来的其他内容,它在乎什么?它与方法的签名匹配。
      • 这是设计使然。正如我在回答中已经解释的那样,帮助程序使用 lambda 表达式从相应的属性中提取元数据。您希望从这样一个执行一些 LINQ 查询的表达式中获得什么元数据?因此,仅支持简单的属性和索引器表达式。
      • 好吧,我的猜测与查询模型时获得的元数据相同。由于显示模板基本上会遍历列表中的所有对象并根据它们的类型创建模板,因此我希望它使用该类型的元数据。它对列表的元数据有什么用吗?我认为它不会为列表属性本身打印出[DisplayName] 之类的东西。但是,是的,我明白它为什么会坏了。
      【解决方案3】:

      第一个示例提供了一个强类型参数。它迫使您从模型中选择一个属性。在第二个更松散类型的情况下,您可以在其中放入任何内容,甚至是模型的无效属性。

      编辑: 令人惊讶的是,我找不到强类型与松散类型的好例子/定义,所以我只给出一个简短的例子。

      如果签名是@html.EditorFor(string propertyName);,那么我在输入名称时可能会打错字,直到运行时才会被发现。更糟糕的是,如果模型上的属性发生变化,它不会引发编译器错误,并且直到运行时才会再次被检测到。这可能会浪费大量时间调试问题。

      另一方面,如果模型的属性发生更改,则会出现编译器错误,如果要编译程序,则必须修复它。 编译时检查总是优于运行时检查。这消除了人为错误或疏忽的可能性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-14
        • 1970-01-01
        • 1970-01-01
        • 2019-07-14
        • 1970-01-01
        • 1970-01-01
        • 2017-07-21
        • 2017-11-06
        相关资源
        最近更新 更多