Search code examples
c#asp.net-mvctemplatesmvc-editor-templateseditorformodel

ASP.NET MVC not finding/using custom type editor template


I'm stuck trying to figure out why my template is not being rendered or found (as breakpoints on template are not being hit). I've got a model like this:

public class SomeModel
{
    public Dropdown Cities { get; set; }
}

used in this view

@model Mvc.Models.SomeNamespace.SomeModel
@{
    Layout = "../Shared/_Site.cshtml";
}

@Html.ValidationSummary(true)

@using (Html.BeginForm())
{
    @Html.EditorForModel()

    <input type="submit" value="Continue">
}

where the Dropdown object definition is

public class Dropdown
{
    public int SelectedValue { get; set; }

    public IEnumerable<SelectListItem> Values { get; set; }

    public string Placeholder { get; set; }
}

I've created an editor template for Dropdown under Views/Shared/EditorTemplates/Dropdown.cshtml

@model Mvc.ViewModels.Dropdown

@Html.DropDownListFor(model => model.SelectedValue, Model.Values, Model.Placeholder)

The shocking thing for me is that I also have DateTime.cshtml template under that path that works just fine.

Every property on the model except for those of Dropdown type are being rendered, even the DateTime ones with its custom template.

Am I unaware of something?

EDIT: Already tried using [UIHint("Dropdown")] at Cities property.

EDIT2: Tried renaming to DropdownViewModel


Solution

  • By default templates do not recurse down into nested complex objects. If you want this to happen you could always override this default behavior by creating a ~/Shared/EditorTemplates/Object.cshtml with the following contents:

    @if (ViewData.TemplateInfo.TemplateDepth > 1) 
    {
        @ViewData.ModelMetadata.SimpleDisplayText
    } 
    else 
    {
        foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit && !ViewData.TemplateInfo.Visited(pm))) 
        {
            if (prop.HideSurroundingHtml)
            {
                @Html.Editor(prop.PropertyName)
            }
            else
            {
                if (!String.IsNullOrEmpty(Html.Label(prop.PropertyName).ToHtmlString()))
                {
                    <div class="editor-label">@Html.Label(prop.PropertyName)</div>
                }
                <div class="editor-field">
                    @Html.Editor(prop.PropertyName)
                    @Html.ValidationMessage(prop.PropertyName, "*")
                </div>
            }
        }
    }
    

    You can read more about the default templates in ASP.NET MVC in this blog post.