简体   繁体   English

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

[英]MVC3 nested partial pages (and viewmodels): How do form fields from get binded?

I have 2 view models like this: 我有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; }
}

Now, I wanted to have a partial page for ViewModel2 and include that in the create page for ViewModel1: 现在,我想为ViewModel2提供一个局部页面,并将其包含在ViewModel1的创建页面中:

Create.cshtml looks something like this Create.cshtml看起来像这样

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

_ViewModel2Create.cshtml looks like _ViewModel2Create.cshtml看起来像

@model ViewModels.ViewModel2
@Html.EditorFor(model => model.ViewModel2Desc )

The problem is, on the Create controller for Model1, nothing gets bound to ViewModel1.ViewModel2 问题是,在Model1的Create控制器上,没有任何东西绑定到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: 未绑定ViewModel2的原因是,当您查看生成的HTML时,您会注意到为该子模型创建的输入字段名称不正确:

<input type="text" name="ViewModel2Desc" />

whereas the correct is: 而正确的是:

<input type="text" name="ViewModel2.ViewModel2Desc" />

The reason for this is that your _ViewModel2Create.cshtml partial doesn't keep the navigational property context of the parent. 这是因为您的_ViewModel2Create.cshtml部分未保留父级的导航属性上下文。

For this reason I would recommend you to use editor templates instead of a partial call: 因此,我建议您使用编辑器模板而不是部分调用:

@model ViewModels.ViewModel1
@using (Html.BeginForm()) {
    @Html.EditorFor(model => model.ViewModel1Desc)
    @Html.EditorFor(model => model.ViewModel2)
}

and then move your partial code inside ~/Views/Shared/EditorTemplates/ViewModel2.cshtml : 然后在~/Views/Shared/EditorTemplates/ViewModel2.cshtml移动您的部分代码:

@model ViewModels.ViewModel2
@Html.EditorFor(model => model.ViewModel2Desc)

Notice the location of the editor template: ~/Views/Shared/EditorTemplates . 注意编辑器模板的位置: ~/Views/Shared/EditorTemplates This is important. 这个很重要。 It is where ASP.NET MVC will look for it. ASP.NET MVC将在其中寻找它。 In fact it will first look in ~/Views/XXX/EditorTemplates where XXX is your current controller name for more specific templates and if it doesn't find one look in the Shared folder. 实际上,它将首先在~/Views/XXX/EditorTemplates中查找,其中XXX是您用于更特定模板的当前控制器名称,如果在共享文件夹中找不到该外观,则为XXX Also notice the name of the file: ViewModel2.cshtml . 还要注意文件名: 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: 您可以覆盖以下内容:

@Html.EditorFor(model => model.ViewModel2, "_ViewModel2Create")

or using an UIHint attribute on your view model: 或在视图模型上使用UIHint属性:

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

and then have ~/Views/Shared/EditorTemplates/_ViewModel2Create.cshtml . 然后具有~/Views/Shared/EditorTemplates/_ViewModel2Create.cshtml

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM