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

发布于 2025-01-07 21:21:53 字数 929 浏览 0 评论 0原文

我有 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; }
}

现在,我想要 ViewModel2 的部分页面并将其包含在 ViewModel1 的创建页面中:

Create.cshtml 看起来像这样

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

_ViewModel2Create.cshtml 看起来像

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

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

我是否以正确的方式执行此操作,或者我应该像这样写出所有字段:

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:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

阳光①夏 2025-01-14 21:21:53

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

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

而正确的是:

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

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

因此,我建议您使用编辑器模板而不是部分调用:

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

然后将部分代码移至 ~/Views/Shared/EditorTemplates/ViewModel2.cshtml 内:

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

注意编辑器模板的位置:~/Views/Shared/EditorTemplates。这很重要。这是 ASP.NET MVC 查找它的地方。事实上,它会首先在 ~/Views/XXX/EditorTemplates 中查找,其中 XXX 是您当前的控制器名称,以获取更具体的模板,如果在共享文件夹。另请注意文件的名称:ViewModel2.cshtml。这也很重要,而且按照惯例是有效的。模板的名称实际上是属性的类型。

您可以覆盖此:

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

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

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

然后使用 ~/Views/Shared/EditorTemplates/_ViewModel2Create.cshtml

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:

<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.

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:

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

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/EditorTemplates where XXX is 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:

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

or using an UIHint attribute on your view model:

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文