如何在razor viewengine中实现foreach委托?

lea*_*ner 3 asp.net asp.net-mvc razor

以下代码适用于webform视图引擎.

<% Model.Categories.ForEach(x => { %>
    <li><a href="#">@x.Name</a></li>
<% }) %>
Run Code Online (Sandbox Code Playgroud)

我在razor视图中编写了以下代码:

@Model.Categories.ForEach(x => {
  <li><a href="#">@x.Name</a></li>
})
Run Code Online (Sandbox Code Playgroud)

但这不起作用.

任何人都可以建议,有没有办法在剃刀视图中实现这一点?

提前致谢.

jev*_*lio 7

你有什么理由要这么做吗?

@foreach(var x in Model.Categories) {
    <li><a href="#">@x.Name</a></li>
}
Run Code Online (Sandbox Code Playgroud)

上面的内容完全相同,更具惯用性.

我看不到.ForEach()使用Razor语法输出委托结果的方法.Razor期望调用方法或调用属性返回一个值,然后将其发送到视图输出中.因为.ForEach()不返回任何东西,它不知道如何处理它:

无法将类型'void'显式转换为'object'

你可以非常简洁地使用迭代器索引:

@foreach (var item in Model.Categories.Select((cat, i) => new { Item = cat, Index = i })) {
   <li><a href="#">@x.Index - @x.Item.Name</a></li>
}
Run Code Online (Sandbox Code Playgroud)

如果要将此定义为扩展方法而不是匿名类型,则可以创建一个类来保存该Item, Index对,并定义一个扩展方法,在IEnumerable<T>该方法yield中,原始可枚举中的项目包含在此构造中.

public static IEnumerable<IndexedItem<T>> WithIndex<T>(this IEnumerable<T> input)
{ 
    int i = 0;
    foreach(T item in input)
        yield return new IndexedItem<T> { Index = i++, Item = item };
}
Run Code Online (Sandbox Code Playgroud)

班级:

public class IndexedItem<T>
{
    public int Index { get; set; }
    public T Item { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

用法:

@foreach(var x in Model.Categories.WithIndex()) {
    <li><a href="#">@x.Index - @x.Item.Name</a></li>
}
Run Code Online (Sandbox Code Playgroud)


lea*_*ner 5

谢谢你的帮助.我根据Phil Haack的以下文章找到了如何在Razor中实现代理. 模板化的剃刀代表

这是IEnumerable的扩展代码:

public static HelperResult ForEachTemplate<TEntity>(
        this IEnumerable<TEntity> items, 
        Func<RowEntity<TEntity>, HelperResult> template)
{
    return new HelperResult(writer =>
               {
                   var index = 0;
                   foreach (var item in items)
                   {
                       template(new RowEntity<TEntity> { 
                               Index = index, 
                               Value = item }).WriteTo(writer);
                       index++;
                   }
               });
}

public class RowEntity<TEntity>
{
    public int Index { get; set; }
    public TEntity Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

查看模型是:

// IEnumerable<Person>

public class Person
{
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

并使用那种扩展方法:

@Model.ForEachTemplate(@<p>Index: @item.Index Name: @Item.Value.Name</p>)
Run Code Online (Sandbox Code Playgroud)