I have 2 view models like this:
public class ViewModel1 // maps to Model1
{
public string ViewModel1Desc { get; set; }
public ViewModel2 ViewModel2 { get; set; }
public ScheduleMasterEditViewModel()
{
ViewModel2= new ViewModel2();
}
}
public class ViewModel2 // maps to Model2
{
public string ViewModel2Desc { get; set; }
}
Now, I wanted to have a partial page for ViewModel2 and include that in the create page for ViewModel1:
Create.cshtml looks something like this
@model ViewModels.ViewModel1
@using (Html.BeginForm()) {
@Html.EditorFor(model => model.ViewModel1Desc )
@Html.Partial("~/Views/ViewModel2/_ViewModel2Create.cshtml", Model.ViewModel2)
}
_ViewModel2Create.cshtml looks like
@model ViewModels.ViewModel2
@Html.EditorFor(model => model.ViewModel2Desc )
The problem is, on the Create controller for Model1, nothing gets bound to ViewModel1.ViewModel2
Am I doing this the right way, or should I just write out all the fields like this:
The reason your ViewModel2 is not bound is because when you look at the generated HTML you will notice that the input fields that were created for this submodel have incorrect names:
whereas the correct is:
The reason for this is that your
_ViewModel2Create.cshtmlpartial doesn’t keep the navigational property context of the parent.For this reason I would recommend you to use editor templates instead of a partial call:
and then move your partial code inside
~/Views/Shared/EditorTemplates/ViewModel2.cshtml:Notice the location of the editor template:
~/Views/Shared/EditorTemplates. This is important. It is where ASP.NET MVC will look for it. In fact it will first look in~/Views/XXX/EditorTemplateswhereXXXis your current controller name for more specific templates and if it doesn’t find one look in the Shared folder. Also notice the name of the file:ViewModel2.cshtml. This also is important and it works by convention. The name of the template is actually the type of the property.You could override this:
or using an
UIHintattribute on your view model:and then have
~/Views/Shared/EditorTemplates/_ViewModel2Create.cshtml.