Razor 是不是支持 lambda 表达式?
Posted
技术标签:
【中文标题】Razor 是不是支持 lambda 表达式?【英文标题】:Are lambda expressions supported by Razor?Razor 是否支持 lambda 表达式? 【发布时间】:2011-06-23 03:21:59 【问题描述】:Razor 视图引擎是否支持 lambda 表达式/匿名方法?
我在 Razor 中难以表达以下内容:
@Model.ToList().ForEach(i =>
if (i.DealerName != null)
<text>
@i.DealerName
</text>
注意:我知道可以用 @foreach
解决这个问题,但我需要一个类似的解决方案来处理第 3 方 MVC 控件。它使用这种机制来设置控件的内容。它适用于 MVC .ASPX 视图,但无法使其与 Razor 一起使用。
MVC .ASPX 等效项(我想转换为 Razor 语法的代码):
<% Model.ToList().ForEach(i =>
if (i.DealerName != null)
%> <%=i.DealerName%> <%
;
);
%>
这适用于 ASP.NET MVC3 附带的 Razor 引擎。
【问题讨论】:
【参考方案1】:您可以使用Response.Write(i.DealerName);
代替<text>@i.DealerName</text>
块
结果是一样的,就像你把它放到 Razor 页面中一样 - 它会在渲染页面时执行。坦率地说 - 我很确定无论如何它都会被编译成这样。
此外,由于ForEach()
返回 void,您必须将其作为代码块放到页面中。
所以你的代码看起来像这样:
@
Model.ToList().ForEach(i =>
if (i.DealerName != null)
Response.Write(i.DealerName);
);
UPD:如果您有更严格的格式,您可以使用这个不错的小技巧: (不幸的是,这里的代码着色不会给这个 sn-p 任何功劳,但如果你把它放到 Visual Studio 中,你肯定会明白我的意思。注意:这仅适用于 Razor 页面,而不适用于代码文件 :))
@
Model.ToList().ForEach(i =>
if (i.DealerName != null)
Response.Write(((Func<dynamic, object>)(
@<text>
<b>Hello Dealer named: @item.DealerName
Multiline support is <em>Beautiful!</em>
</text>)).Invoke(i));
);
希望这是有道理的:)
【讨论】:
是的Response.Write
有效,但对于更复杂的示例,字符串连接很快就会失控。 :(
是的,你是对的..我已经更新了帖子以允许在这个函数中使用几乎任何类型的 Razor 代码.. 享受:)
感谢您使用 Artiom 的麻烦。我特别喜欢你的多线技巧。不幸的是,我不能进入这样的代码块。正如我在问题中提到的,我需要在组件供应商 lambda 表达式中提供我的内容/模板来构建控件。 .ASPX 代码看起来很简单。我是否认为 Razor 不支持与 MVC .ASPX 代码相同级别的 lambda 表达式?
等等.. 但是在您的 .aspx 示例中,您正在做同样的事情.. 您正在打开一个代码块,并在那里执行一个 .ForEach 方法.. 当然您应该能够在 Razor 控件中做同样的事情.. 至少我从来没有遇到过任何问题
Hmm.. 请注意,我认为不是每个人都知道您可以将@ code goes here
块放在剃须刀页面的任何位置,而不仅仅是作为 .cshtml 文件的“头”。事实上,如果您想在 aspx 中间运行 void
方法或创建新变量,您必须使用这样的代码块 :)【参考方案2】:
或者,您可以创建一个 lambda 函数,并为 Razor 代码主体中的每个项目调用它(这个想法来自 this post 中的 Andy):
@model IEnumerable<Dealer>
@
Func<Dealer, object> sayHi =
@<text>
<b>Hello Dealer named: @(item.DealerName)</b>
Multiline support is <em>Beautiful!</em>
</text>;
<div>
@foreach(var dealer in Model.ToList())
sayHi(dealer);
</div>
【讨论】:
【参考方案3】:是的,它们受支持。但是,Razor 有一些奇怪的转义规则,额外的大括号有时会导致它阻塞,包括扩展 lambda 表达式中的那些。
您可以稍微简化@Artioms 的答案,以使用 where 和可选的 select 子句删除那些额外的大括号
@
Model.ToList().ForEach(i =>
if (i.DealerName != null)
Response.Write(i.DealerName);
);
变成
@
Model.Where(i=>i.DealerName != null).ToList().ForEach(i =>
Response.Write(i.DealerName);
);
也可以变成
@Model.Where(i=>i.DealerName != null).Select(i=>i.DealerName)
.ToList().ForEach(Response.Write);
是的功能样式!
【讨论】:
感谢您的反馈,但它没有回答问题。 我对顶部进行了重新措辞,使其更加清晰 - 它改进了@Artioms 的答案。我还提供了另一种解决方法 - 删除可能会混淆剃刀编译器的额外大括号。我认为它至少很有用。以上是关于Razor 是不是支持 lambda 表达式?的主要内容,如果未能解决你的问题,请参考以下文章
lambda 函数是不是可以包含 Razor 语法并在视图中执行?
asp mvc razor 存储 lambda 表达式以列出并重用它
java: -source 1.5 中不支持 lambda 表达式 (请使用 -source 8 或更高版本以启用 lambda 表达式)??