model-view-controllereditorforeditortemplates

Selecting an alternate EditorFor template for a List


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!


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])
        }
    }