I’ve got a view model as:
public class AttributeEditorViewModel
{
public long AttributeId { get; set; }
public string DisplayName { get; set; }
public object Value { get; set; }
}
The model is build using a model builder so that a final view model has a list of above objects:
public class AttributeListViewModel
{
public List<AttributeEditorViewModel> Attributes { get; set; }
}
My model builder compiled a list of AttributeEditorViewModel object and sets appropriate primitive type to the Value property. The data type comes from separate definitions of attributes.
Now the Razor view (lets say edit.cshtml) looks something like:
@model AttributeListViewModel
@Html.EditorFor(m => m.Attributes)
and the editor template Views/Shared/EditorTemplates/AttributeEditorViewModel.cshtml:
@model AttributeEditorViewModel
<div>
<label>@Model.DisplayName</label>
@Html.EditorFor(m => m.Value)
@Html.ValidationMessageFor(m => m.Value)
</div>
What I would expect; If I set the Value property of a AttributeEditorViewModel to a double, like so:
public ActionResult Edit()
{
return View(new AttributeListViewModel
{
Attributes = new List<AttributeEditorViewModel>
{
new AttributeEditorViewModel { DisplayName = "Double example", Value = (double) 0 }
}
};
}
I would expect that a text box would be rendered. Instead it renders nothing. I’ve added another editor template Views/Shared/EditorTemplates/Double.cshtml:
@model double
@Html.TextBoxFor(m => m)
Which solved the immediate problem. So now I get a textbox with value 0 in it. However using the EditorFor even inside the custom editor template again renders nothing.
Is it fundamentally wrong to use object as base type for this? Why is it rendering nothing when EditorFor or EditorForModel is used?
Any insight appreciated.
It’s because EditorFor uses compile-time binding on the generic parameters to determine which template to render.
And since there’s no
EditorFor<object>()defined by default, you get nothing.I believe you can define your own editor template for object if you want, but probably a better way would be to make your view model generic:
However, this might not be ideal as you could no longer have a list of polymorphic view models.