Using a DisplayTemplate (with DisplayFor) for each item in the collection

I created a DisplayTemplate for the Comment class and placed it inside Comment/DisplayTemplates/Comment.cshtml .

Comment.cshtml correctly printed:

 @model Comment 

Then I have a partial view that takes an IEnumerable<Comment> model for the model. There I browse the collection and want to use the DisplayTemplate for the Comment class. Representation in its integrity:

 @model IEnumerable<Comment> @foreach (var comment in Model.Where(c => c.Parent == null)) { @Html.DisplayFor(model => comment) } 

However, I get an error in the Html.DisplayFor line:

The model element passed to the dictionary is of type "System.Int32", but for this dictionary a model element of type "System.String" is required.

How can I call a DisplayTemplate for each element in a foreach ?

+20
asp.net-mvc asp.net-mvc-3 razor
Apr 13 2018-11-11T00:
source share
2 answers

Instead of having a view that accepts an IEnumerable<Comment> , and all it does is loop through the collection and just call the correct display pattern:

 @Html.DisplayFor(x => x.Comments) 

where the Comments property is an IEnumerable<Comment> , which automatically loops and displays the Comment.cshtml display Comment.cshtml for each element of this collection.

Or, if you really need that look (I don’t know why), you could simply:

 @model IEnumerable<Comment> @Html.DisplayForModel() 

As for the Where clause that you use there, you should simply delete it and delegate this task to the controller. The responsibility of the dispatcher is to prepare the presentation model, and not the presentation that performs such tasks.

+31
Apr 13 2018-11-11T00:
source share

While the accepted answer works well in most cases, there are other cases where we need to know the index of the element when rendering (i.e. add custom javascript that generates links to each element based on their index).

In this case, DisplayFor can still be used in a loop as follows:

 @model IEnumerable<Comment> @for (int index = 0; index < Model.Count(); index++) { @Html.DisplayFor(model => model[index]) } 
+12
Feb 16 '12 at 13:41
source share



All Articles