I have what appears (to me anyway) to be a strange problem...
I created a simple editor template for a SelectListItem (SelectListItem.cshtml in the ~/Views/Shared/EditorTemplates folder), for example:
<ul class="select-list-item cell-15 col-3 omega clearfix"> @Html.EditorFor(c => c.Categories) </ul>
Where c.Categories is an IEnumerable
This worked fine, but I wanted another template to render the collection with slightly different markup, so I copied and renamed the editor template to, for example, 'CategoryIcons.cshtm' and invoked as follows:
<ul class="select-list-item cell-15 col-3 omega clearfix"> @Html.EditorFor(c => c.Categories, "CategoryIcons") </ul>
In short, the only difference is I'm specifying a named editor template.
When I open the page, I now get the following error:
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[System.Web.Mvc.SelectListItem]', but this dictionary requires a model item of type 'System.Web.Mvc.SelectListItem'
The template's model declaration, in both templates id:
@model System.Web.Mvc.SelectListItem
I don't understand why the default template works and the named template doesn't. Any help would be appreciated.
Thanks.
ASP.NET MVC includes the method that generates HTML input elements based on the datatype. The Html. Editor() or Html. EditorFor() extension methods generate HTML elements based on the data type of the model object's property.
TextBoxFor will always show the textbox element no matter which kind of property we are binding it with. But EditorFor is much flexible in this case as it decides which element will be more suitable to show the property.
EditorFor does not allow for styling as there are no parameters for additional attributes. The reason for this is because the EditorFor doesn't always generate a single element as it can be overridden. To style a specific type of element you need to use the specific editor you want to use.
When you call @Html.EditorFor(c => c.Categories)
it is falling back to the default template for IEnumerable. This default template is provided by the MVC framework, and its behaviour is to output Html.EditorFor()
for each item in the enumeration. That in turn emits the appropriate editor template for each item in the list individually - in your case they're all instances of SelectListItem
, so in the first case, the SelectListItem
template is used for each item.
In the second case, by explicitly setting your EditorFor
to use a particular editor template CategoryIcons
, you are telling it to use that editor template for the whole enumeration, instead of allowing the enumerable to be templated by default, in turn using the template for each enumerated item.
I'm not sure of the best way around this just yet.
One approach would be to define a CategoryIcons
template, whose model is an instance of IEnumerable<CategoryIcon>
, which simply foreaches the Model
enumeration, and performs Html.EditorFor
for each item, with an explicit template reference of CategoryIcon
. You then put your per-item editor template in that template (CategoryIcon
not CategoryIcons
). You would then call this by doing @Html.EditorFor(c => c.Categories, "CategoryIcons")
.
I'm going to have a look around to see if there are better ways to get this done, but I hope this might be useful for now. It would be great if templates could be parameterized, so you could write an IEnumerable template that takes as an argument the name of the template to use for each of its items.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With