How to implement foreach delegate in razor viewengine?
The following code works for webform view engine.
<% Model.Categories.ForEach(x => { %>
<li><a href="#">@x.Name</a></li>
<% }) %>
I wrote the above code as below in razor view:
@Model.Categories.ForEach(x => {
<li><a href="开发者_StackOverflow社区#">@x.Name</a></li>
})
But this doesn't work.
Can anyone suggest, Is there any way to achieve this in razor view?
Thanks in advance.
Is there any reason you need to do that?
@foreach(var x in Model.Categories) {
<li><a href="#">@x.Name</a></li>
}
Above does the exact same thing, and is more idiomatic.
I can't see a way to output the .ForEach()
delegate result using the Razor syntax. Razor expects called methods or invoked properties to return a value, which is then emitted into the view output. Because .ForEach()
doesn't return anything, it doesn't know what to do with it:
Cannot explicitly convert type 'void' to 'object'
You can have the iterator index quite tersely like so:
@foreach (var item in Model.Categories.Select((cat, i) => new { Item = cat, Index = i })) {
<li><a href="#">@x.Index - @x.Item.Name</a></li>
}
If you want to define this as an extension method, instead of an anonymous type, you can create a class to hold the Item, Index
pair, and define an extension method on IEnumerable<T>
which yield
s the items in the original enumerable wrapped in this construct.
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 };
}
The class:
public class IndexedItem<T>
{
public int Index { get; set; }
public T Item { get; set; }
}
Usage:
@foreach(var x in Model.Categories.WithIndex()) {
<li><a href="#">@x.Index - @x.Item.Name</a></li>
}
Thanks for your help. I found how to implement delegates in Razor based on the following article by Phil Haack. Templated Razor Delegates
Here is the extension code for 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; }
}
View Model is :
// IEnumerable<Person>
public class Person
{
public string Name { get; set; }
}
And the use of that extension methods:
@Model.ForEachTemplate(@<p>Index: @item.Index Name: @Item.Value.Name</p>)
精彩评论