Question

I have an object that represents a food item to order at a restaurant. This object has a list of Modifier Groups (sides, cooking instructions, pizza toppings, whatever) and each list has a list of Modifiers.

Certain Modifier options need to be displayed differently (for example, toppings need to specify left/right/all), even though they are the same data type.

I am trying use @Html.EditorFor and specify the alternate EditorTemplate when required.

In /Views/Shared/EditorTemplates I have ModifierSelection.cshtml and ToppingSelection.cshtml. I am calling them in the following view:

@model MyApp.ViewModels.ModifierSelectionList

<div class="menugroup">
    <h3 class="menuname">@Model.ModifierListName: (Select @Model.MaximumSelections)</h3>
    <div class="modcountvalidation">@Model.ValidationResults</div>
    @Html.HiddenFor(model => Model.ModifierListId)

    <table class="menu">
    @if (Model.IsToppingsList)
    {
        @Html.EditorFor(model => Model.ModifierSelections, "ToppingSelection")
    }
    else
    { 
        @Html.EditorFor(model => Model.ModifierSelections)
    }
    </table>
</div>

When I try to display an item that requires the "ToppingSelection" EditorTemplate instead of the default, I get the following error:

System.InvalidOperationException was unhandled by user code
  Message=The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[MyApp.ViewModels.ModifierSelection]', but this dictionary requires a model item of type 'MyApp.ViewModels.ModifierSelection'.
  Source=System.Web.Mvc

So - I have a set of EditorTemplates for a data type. I am trying to use them to display a list of items and I need to be able to select which one to use.

What am I doing wrong?

Thanks!

Was it helpful?

Solution

OK, here is the real solution. Rather than iterating through the list using foreach, I had to iterate using a for loop.

@for (int i = 0; i < Model.ModifierSelections.Count; i++ )
{
    if (Model.IsToppingsList)
    {
        @Html.EditorFor(m => Model.ModifierSelections[i], "ToppingSelection")
    }
    else
    { 
        @Html.EditorFor(m => Model.ModifierSelections[i])
    }
}

OTHER TIPS

Solved!

Apparently, if you send a list type to Html.EditorFor and do not specify a template, it will iterate through the list and display each item using the template that it finds for the item type. If you do specify a template, it will not iterate through the list and send each item to that template, it will attempt to send the entire list to your template, which isn't the right data type.

I fixed it by manually iterating through the list:

@foreach (var modifierSelection in Model.ModifierSelections)
{
    if (Model.IsToppingsList)
    {
        @Html.EditorFor(m => modifierSelection, "ToppingSelection")
    }
    else
    { 
        @Html.EditorFor(m => modifierSelection)
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top