MVC3嵌套的部分页面(和视图模型):如何从绑定表单字段?

get*_*tit 1 asp.net-mvc bind nested partials viewmodel

我有2个这样的视图模型:

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; }
}
Run Code Online (Sandbox Code Playgroud)

现在,我希望有一个ViewModel2的部分页面,并将其包含在ViewModel1的创建页面中:

Create.cshtml看起来像这样

@model ViewModels.ViewModel1
@using (Html.BeginForm()) {
    @Html.EditorFor(model => model.ViewModel1Desc )
    @Html.Partial("~/Views/ViewModel2/_ViewModel2Create.cshtml", Model.ViewModel2)
}
Run Code Online (Sandbox Code Playgroud)

_ViewModel2Create.cshtml看起来像

@model ViewModels.ViewModel2
@Html.EditorFor(model => model.ViewModel2Desc )
Run Code Online (Sandbox Code Playgroud)

问题是,在Model1的Create控制器上,没有任何内容绑定到ViewModel1.ViewModel2

我是以正确的方式做到这一点,还是应该写出所有这样的字段:

Dar*_*rov 5

您的ViewModel2未绑定的原因是,当您查看生成的HTML时,您会注意到为此子模型创建的输入字段具有不正确的名称:

<input type="text" name="ViewModel2Desc" />
Run Code Online (Sandbox Code Playgroud)

而正确的是:

<input type="text" name="ViewModel2.ViewModel2Desc" />
Run Code Online (Sandbox Code Playgroud)

原因是您的_ViewModel2Create.cshtmlpartial不保留父级的导航属性上下文.

出于这个原因,我建议你使用编辑器模板而不是部分调用:

@model ViewModels.ViewModel1
@using (Html.BeginForm()) {
    @Html.EditorFor(model => model.ViewModel1Desc)
    @Html.EditorFor(model => model.ViewModel2)
}
Run Code Online (Sandbox Code Playgroud)

然后在里面移动你的部分代码~/Views/Shared/EditorTemplates/ViewModel2.cshtml:

@model ViewModels.ViewModel2
@Html.EditorFor(model => model.ViewModel2Desc)
Run Code Online (Sandbox Code Playgroud)

注意编辑器模板的位置:~/Views/Shared/EditorTemplates.这个很重要.它是ASP.NET MVC寻找它的地方.事实上,它会先看看在~/Views/XXX/EditorTemplates哪里XXX是你的电流控制器名称更具体的模板,如果它没有找到在共享文件夹一看.还要注意文件的名称:ViewModel2.cshtml.这也很重要,它按惯例运作.模板的名称实际上是属性的类型.

你可以覆盖这个:

@Html.EditorFor(model => model.ViewModel2, "_ViewModel2Create")
Run Code Online (Sandbox Code Playgroud)

UIHint在视图模型上使用属性:

public class ViewModel1
{
    public string ViewModel1Desc { get; set; }
    [UIHint("_ViewModel2Create")]
    public ViewModel2 ViewModel2 { get; set; }
    public ScheduleMasterEditViewModel()
    {
        ViewModel2 = new ViewModel2();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后有~/Views/Shared/EditorTemplates/_ViewModel2Create.cshtml.