Asp.net mvc 为什么许多MVC html助手使用委托作为输入参数

Asp.net mvc 为什么许多MVC html助手使用委托作为输入参数,asp.net-mvc,asp.net-mvc-3,delegates,html-helper,mvc-editor-templates,Asp.net Mvc,Asp.net Mvc 3,Delegates,Html Helper,Mvc Editor Templates,在MVC中,如果要为属性创建编辑器或为属性创建显示,请执行以下操作: @Html.EditorFor(m=> m.MyModelsProperty); @Html.DisplayFor(m=> m.MyModlesProperty); 为什么我们必须传递委托?为什么我们不能直接传递模型的属性?e、 g: @html.EditorFor(Model.MyModlesProperty); 这是因为元数据。您知道,您可以在模型上添加的所有属性,如[必需],[显示名称],[显示格式]。。

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

@Html.EditorFor(m=> m.MyModelsProperty);
@Html.DisplayFor(m=> m.MyModlesProperty);
为什么我们必须传递委托?为什么我们不能直接传递模型的属性?e、 g:

@html.EditorFor(Model.MyModlesProperty);

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

lambda表达式允许分析模型上的属性并从中读取元数据。然后辅助对象变得智能化,并且基于您指定的属性将采取不同的操作


因此,通过使用lambda表达式,helper能够完成比仅仅显示一些值更多的事情。它可以格式化此值,它可以验证此值,

第一个示例提供了一个强类型的参数。它强制您从模型中选择特性。如果第二个是松散类型的,则可以在其中放入任何内容,甚至是模型的无效属性

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

如果签名是
@html.EditorFor(string propertyName)
然后我可以在键入名称时输入错误,直到运行时才会被捕获。更糟糕的是,如果模型上的属性发生更改,它不会抛出编译器错误,并且在运行时之前不会再次被检测到。这可能会浪费大量时间调试问题


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

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

表达式允许您知道属性的名称,而无需将字符串硬编码到项目中。如果您检查由MVC生成的HTML,您将看到您的输入字段被命名为
“ModelType\u PropertyName”
,这将允许
模型绑定器创建复杂类型,并将其传递给控制器操作,例如:

public ActionResult Foo(MyModel model) { ... }
另一个原因是
Linq到SQL
。表达式树是将lambda转换为SQL查询所必需的魔法。因此,如果你要做如下事情:

Html.DisplayFor(p => p.Addresses.Where(j => j.Country == "USA"))
如果DbContext仍然打开,它将执行查询

更新

划掉一个错误。你每天都在学习新的东西。

因此,如果你要做诸如:Html.DisplayFor(p=>p.Addresses.Where(j=>j.Country==“USA”)
这样的事情,你就不能做任何事情。仅支持简单表达式(属性和索引器访问)。这将失败并出现错误。@DarinDimitrov-Huh。。你说得对。但是为什么呢?如果它必须显示我的
IList
或我刚刚从中查询到的其他内容,它关心什么?它与方法的签名相匹配。这是出于设计。正如我在回答中已经解释的,助手使用lambda表达式从相应的属性中提取元数据。您希望从这样一个执行LINQ查询的表达式中获得什么元数据?由于这个原因,只支持简单的属性和索引器表达式。好吧,我猜在查询模型时得到的元数据是相同的。由于显示模板基本上会遍历列表中的所有对象,并根据它们的类型创建模板,因此我希望它使用该类型的元数据。它对列表的元数据有什么用处吗?我认为它不会为list属性本身打印类似于
[DisplayName]
的内容。但是是的,我明白它为什么坏了。