UIHint not using EditorTemplate

2019-07-12 08:46发布

问题:

I have a model like this:

public class MyModel {
    [ScaffoldColumn(false)]
    public int CharityId { get; set; }

    [UIHint("Charities")]
    public SelectList Charities { get; set; }
}

Then I have an EditorTemplate called Charities.cshtml:

@model MyModel

@Html.DropDownListFor(model => model.CharityId, Model.Charities)

Then in my page:

@model MyModel

@Html.EditorForModel()

However, no matter what, it doesn't render the Charities template. I've been wracking my brain on this, and it should work.. but it's not.

Any ideas?

EDIT:

The issue is that the default Object template will not render a complex object other than itself (so called shallow dive), even if there is a UIHint. I was under the impression that a UIHint would make it render the template, but I was apparently wrong.

The fix is to not try to let the model render itself. That is sad.

回答1:

First things first @EditoFormodel() in your page looks bizarre. I guess you meant something else.

Now to the point: you have decorated the Charities property with UIHint. This property is of type SelectList. This means that the Charities.cshtml template should be strongly typed to SelectList, not to MyModel as you did. You could simply remove this UIHint attribute and have the following view model:

public class MyModel {
    [ScaffoldColumn(false)]
    public int CharityId { get; set; }

    public SelectList Charities { get; set; }
}

and in your view:

@model MyModel
@Html.EditorForModel()

and then inside ~/Views/Shared/EditorTemplates/MyModel.cshtml have:

@model MyModel
@Html.DropDownListFor(model => model.CharityId, Model.Charities)

That's the standard conventions. If you want your editor template to be called Charities.cshtml you could do this in your page:

@model MyModel
@Html.EditorForModel("Charities")

But usually you would have the following model:

public class FooViewModel
{
    [UIHint("Charities")]
    public MyModel Charities { get; set; }
}

Now if your main view is strongly typed to FooViewModel you can:

@model FooViewModel
@Html.EditorFor(x => x.Charities)

which will render the Charities.cshtml editor template.