【问题标题】:Posting multiple forms on MVC Razor View with a Single View Model使用单一视图模型在 MVC Razor 视图上发布多个表单
【发布时间】:2017-01-15 13:36:44
【问题描述】:

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

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

ProductViewModel 的属性如下所示:

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

我的剃刀视图如下所示:

@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");}
}

当点击 Save 按钮时,我最终进入了 A 控制器的 Save (POST) Action Method,正如我所期望的那样:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Save(AViewModel viewModel)
    {
        return Ok();
    }

但是,我注意到 viewModel 参数的所有属性都是空的。

这是否意味着我真的必须将 ProductViewModel 对象作为我的 ViewModel 传递给所有 5 个表单的保存操作方法,其中只有范围内的 ViewModel 将被填充,其他所有内容都将为空?还是有更好的办法?

【问题讨论】:

    标签: c# razor asp.net-core asp.net-core-mvc


    【解决方案1】:

    我建议将每个表单都设为局部视图,并仅传入父模型所需的子模型

     @{await Html.RenderPartialAsync("AViewPartial", Model.AViewModel); }
    

    那么您在部分中的输入可以更改为

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

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

    这应该使它被模型绑定器正确绑定,以便它被传递到您的操作中

    【讨论】:

    • 局部视图正是我需要的。谢谢!
    【解决方案2】:

    POST 方法的参数必须是ProductViewModel

    这是因为属性在 HTML 中的命名方式:

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

    模型绑定器采用您的序列化表单,并看到您正在向 POST 方法发送一个名为 AViewModel.Name 的属性的值。当您的参数类型为 AViewModel 时,它什么也找不到,因为它正在寻找名称为 AViewModel 的参数类型的 子属性,然后分配 对象的Name 属性为输入值。

    如果您不想将每个 POST 方法的参数设置为 ProductViewModel,那么您有一个领先的替代方案:为您的五种不同表单创建局部视图,并从您的 ProductViewModel 中传递各个属性作为局部视图的模型。然后,这将从您的 asp-for 属性中消除 AViewModel 属性前缀。

    【讨论】:

      猜你喜欢
      • 2015-07-23
      • 1970-01-01
      • 1970-01-01
      • 2014-09-27
      • 1970-01-01
      • 2015-04-18
      • 2021-04-10
      • 2014-08-15
      • 2014-06-25
      相关资源
      最近更新 更多