在MVC中,如果要为属性创建编辑器或为属性创建显示,请执行以下操作:
@Html.EditorFor(m=> m.MyModelsProperty);
@Html.DisplayFor(m=> m.MyModlesProperty);
为什么我们必须传递委托为什么我们不能直接传递模型的属性? e.g:
@html.EditorFor(Model.MyModlesProperty);
答案 0 :(得分:2)
原因在于元数据。您知道,您可以在模型上添加的所有属性,例如[Required]
,[DisplayName]
,[DisplayFormat]
,......所有这些属性都是从lambda表达式中提取的。如果您刚刚传递了一个值,则帮助程序将无法从中提取任何元数据。这只是一个虚拟值。
lambda表达式允许分析模型上的属性并从中读取元数据。然后帮助程序变得聪明,并且基于您指定的属性将采取不同的行为。
因此,通过使用lambda表达式,助手除了显示某个值之外还能做更多的事情。它能够格式化这个值,它能够验证这个值,......
答案 1 :(得分:1)
我想补充一点,除了元数据并使Html助手强烈输入到Model类型之外,还有另一个原因:
表达式允许您了解属性的名称,而无需将字符串硬编码到项目中。如果检查由MVC生成的HTML,您将看到输入字段名为"ModelType_PropertyName"
,然后允许Model Binder
创建传递给Controller Actions的复杂类型,如下所示: / p>
public ActionResult Foo(MyModel model) { ... }
另一个原因是Linq to SQL
。表达式树是将Lambda转换为SQL查询所必需的神奇功能。 所以如果你做的事情如下:
Html.DisplayFor(p => p.Addresses.Where(j => j.Country == "USA"))
并且您的DbContext仍处于打开状态,它将执行查询。
<强>更新强>
划出一个错误。你每天都学到新东西。
答案 2 :(得分:0)
第一个示例提供了强类型参数。它会强制您从模型中选择一个属性。如果第二个更强松散类型,您可以在其中放置任何内容,甚至是模型的无效属性。
修改强> 令人惊讶的是,我找不到一个强有力的松散打字的好例子/定义,所以我只是给出一个简短的例子。
如果签名是@html.EditorFor(string propertyName);
,那么我可以在输入名称时输入拼写错误,直到运行时才会被捕获。更糟糕的是,如果模型上的属性发生了变化,它就不会抛出编译器错误,并且在运行时才会再次检测到错误。这可能会浪费大量时间来调试问题。
另一方面,对于lambada,如果模型的属性发生了变化,则会出现编译错误,如果要编译程序,则必须修复它。 编译时检查始终优先于运行时检查。这消除了人为错误或疏忽的可能性。