Take the following models as an example:
namespace MyNamespace.Model
{
//you can only have two friends for the sake of simplicity in this example :P
public class Friends{
public Person NormalFriend { get; set; }
public Hipster HipsterFriend { get; set; }
}
public class Person{
public string Name { get; set; }
public string PhoneNumber { get; set; }
}
public class Hipster : Person
{
public HatType HatPreference { get; set; }
public int CoolPoints { get; set; }
}
}
Let's say we're trying to add our two friends, a normal friend and a hipster friend:
Create.cshtml:
@model MyNamespace.Model.Friends
<div class='container'>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
@Html.AntiForgeryToken()
@Html.EditorFor(model => model.NormalFriend) //uses Person EditorTemplate by convention
@Html.EditorFor(model => model.HipsterFriend) //uses Hipster EditorTemplate by convention
</div>
EditorTemplates/Person.cshtml:
@model MyNamespace.Model.Person
<div class='row'>
<div class='col'>
@Html.EditorFor(model => model.Name)
</div>
<div class='col'>
@Html.EditorFor(model => model.PhoneNumber)
</div>
</div>
EditorTemplates/Hipster.cshtml:
@model MyNamespace.Model.Hipster
@Html.EditorFor(model => model, "Person") // <-- what I've tried and it isn't working
<div class='row'>
<div class='col'>
@Html.EditorFor(model => model.CoolPoints)
</div>
<div class='col'>
@Html.EditorFor(model => model.HatPreference)
</div>
</div>
In the Hipster
EditorTemplate, the code
@Html.EditorFor(model => model, "Person")
should pass the Hipster
model to the Person
EditorTemplate so that I don't have to repeat the Templated Code for shared properties (of the base type Person
).
Currently, the above code just completely ignores the EditorFor
and only displays the Hipster
specific properties(ie CoolPoints
and HatPreference
).
Alternatively, I could change the following code in Create.cshtml:
@Html.EditorFor(model => model.NormalFriend)
@Html.EditorFor(model => model.HipsterFriend)
to:
@Html.EditorFor(model => model.NormalFriend)
@Html.EditorFor(model => model.HipsterFriend, "Person") //break convention and the idea of nesting
@Html.EditorFor(model => model.HipsterFriend)
which will achieve what I want, but it seems wrong that I am unable to do this in the Hipster
EditorTemplate.
Is my logic flawed on this or am I missing something? I thought it possibly could be disregarding the line in question for fear of recursion but the templateName
argument should clarify. This idea of inheriting the base type and nesting works with partials but partials don't handle ViewData.TemplateInfo.GetFullHtmlFieldName
s of complex objects which are necessary for validation.
This question is related: In an Editor Template call another Editor Template with the same Model although the solution isn't applicable in my situation. Is there a workaround to nest the views without using partials or is that my only way?