在MVC Razor视图上发布多个表单,使用一个视图模型

9
我是一名有用的助手,可以为您翻译文本。

我有一个 Razor 视图,其中包含 5 个表单 (A、B、C、D、E)。每个表单都有自己的 ViewModel (AViewModel、BViewModel、CViewModel、DViewModel、EViewModel)。

我创建了一个父 ProductViewModel,页面将使用它作为唯一的 ViewModel。在此 ViewModel 中,将包含页面上每个表单的所有其他 ViewModels (如上所述)。

以下是 ProductViewModel 的属性:

public AViewModel { get; set; }
public BViewModel { get; set; }
public CViewModel { get; set; }
public DViewModel { get; set; }
public EViewModel { get; set; }

我的 Razor 视图如下所示:

@model MVCApp.ViewModels.ProductViewModel

@{
    ViewData["Title"] = "Product Detail";
}

<h2>Product Detail</h2>

<form asp-controller="A" asp-action="Save" data-ajax="true" data-ajax-method="POST">
    <div class="form-horizontal">
        <h4>Form A</h4>
        <hr />
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="AViewModel.Name" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="AViewModel.Name" class="form-control"/>
                <span asp-validation-for="AViewModel.Name" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="AViewModel.StartDate" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="AViewModel.StartDate" class="form-control"/>
                <span asp-validation-for="AViewModel.StartDate" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="AViewModel.EndDate" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="AViewModel.EndDate" class="form-control"/>
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
</form>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

当点击保存按钮时,我会进入 A 控制器的保存(POST)操作方法,就像我预期的那样:
    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Save(AViewModel viewModel)
    {
        return Ok();
    }

然而,我注意到viewModel参数的所有属性都是空的。这是否意味着我必须将ProductViewModel对象作为我的ViewModel传递给Save Action方法,在这5个表单中只有范围内的ViewModel将被填充,其他所有内容都将为空?还是有更好的方法?
2个回答

7
我建议将每个表单制作为部分视图,并仅传递从父模型中所需的子模型。
 @{await Html.RenderPartialAsync("AViewPartial", Model.AViewModel); }

那么您在局部视图中的输入可以更改为:
<input asp-for="AViewModel.Name" class="form-control"/>

to

<input asp-for="Name" class="form-control"/>

这应该使其正确地绑定到模型绑定器,因此它会被传递到您的操作中。


部分视图正是我在这里需要的。谢谢! - Blake Rivell

2

您需要将POST方法的参数设置为ProductViewModel

原因是由于HTML中属性的命名方式:

<input asp-for="AViewModel.Name" class="form-control"/>

模型绑定器接收你序列化的表单,并发现你通过POST方法发送了一个名为AViewModel.Name的属性值。当你的参数是AViewModel类型时,它找不到任何东西,因为它正在查找你的参数类型的子属性,其名称为AViewModel,然后将该对象Name属性分配给输入值。
如果你不想使每个POST方法的参数都是ProductViewModel,那么你有一个主要的替代方案:为你的五个不同表单创建部分视图,并将ProductViewModel的各个属性作为部分视图的模型传递。这将消除你的asp-for属性中的AViewModel属性前缀。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接