ASP.NET MVC 4.5将部分视图映射到表单上的主视图提交

时间:2017-03-08 16:50:45

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

Hello Mighty Stackoverflowers,

我目前正在开发ASP.NET MVC 4.5应用程序。 当我提交创建表单时,我需要将输入值从部分视图映射到主视图模型。

在我的视图" Create.cshtml" 中,我调用了部分视图" _SwotPart.cshtml" 。我将ViewModel的一部分传递给Partial View,如下所示:

Create.cshtml:

@model MyCoolApp.BLL.Models.MainVm

@foreach (var swot in Model.Swots)
{
        <tr>
            @foreach (var swotPart in swot.SwotParts)
            {
                @Html.Partial("~/Views/Shared/_SwotPart.cshtml", swotPart)
            }
        </tr>
}

我的部分视图如下所示,_SwotPartial.cshtml:

<td class="form-group">
    @Html.TextAreaFor(model => model.Label, htmlAttributes: new { Name = nameField, ID = nameField, @class = "form-control", placeholder = Model.SwotTypeId.GetLabel() })
</td>

无论如何,当我提交表单时,部分视图中的值永远不会到达控制器。

您有什么想法如何正确映射?

谢谢!

2 个答案:

答案 0 :(得分:0)

问题在于输入名称将以您当前尝试实现此目的的方式生成。剃刀需要整个列表的上下文,或者至少是项目中的位置,以便生成正确的输入名称。换句话说,解决问题的最简单方法(需要注意)是:

@for (var i = 0; i < Model.Swots.Count(); i++)
{
    ...

    @for (var j = 0; j < Model.Swots[i].SwotParts.Count(); j++)
    {
        if (Model.Swots[i].SwotParts[j].SwotTypeId == SwotType.InternalHelpful || Model.Swots[i].SwotParts[j].SwotTypeId == SwotType.InternalHarmful)
        {
            @Html.Partial("~/Views/Shared/_SwotPart.cshtml", Model.Swots[i].SwotParts[j])
        }
    }

    ...

然后,partial具有正确的上下文,您的输入将被命名为Swots[0].SwotParts[0].Label,模型绑定器将能够使用它。

然而,这里需要注意的是,您将此列表拆分为两个循环。这仍然不会起作用,因为你有效地搞乱了模型中项目位置的整体背景。要解决这个问题,您应该在模型中拆分列表,这样无论如何都会更好,因为您可以从视图中删除此业务逻辑:

public class SwotVm
{
    ...

    public List<SwotPartVm> InternalSwotParts { get; set; }
    public List<SwotPartVm> ExternalSwotParts { get; set; }
}

然后,您可以单独迭代每个列表,这些值自然会回发到相应的列表。

鉴于您使用部分渲染特定类类型的字段,您可以通过创建编辑器模板来获得更好的服务。如果您只是将部分代码移至视图:Views\Shared\EditorTemplates\SwotPartVm.cshtml,则可以在主视图中执行以下操作:

@for (var i = 0; i < Model.Swots.Count(); i++)
{
    ...

    <tr>
        <th class="swot-heading">Internal</th>
        @Html.EditorFor(m => m.Swots[i].InternalSwotParts)
    </tr>
    <tr>
        <th class="swot-heading">External</th>
        @Html.EditorFor(m => m.Swots[i].ExternalSwotParts)
    </tr>
}

显而易见的很多更清洁,你可以通过添加SwotVm.cshtml编辑器模板进一步采用这个概念,只需用以下代码替换这一小部分代码:

@Html.EditorFor(m => m.Swots)

注意:在SwotVm.cshtml编辑器模板中,您只需包含单个SwotVm的代码。换句话说,不包括for语句。

答案 1 :(得分:0)

为了让您的应用程序正确解析发布的值并将其绑定到您的视图模型。发布的表单数据的名称必须类似。

<强> SWOTS [X1] .swotParts [X2] .label

其中x1是每个swot的0到up的数字。 其中x2是swots中每个swot部分的0到up范围内的数字。

现在发布时,表单数据名称只是标签

而不是:

 @Html.TextAreaFor(model => model.Label, htmlAttributes: new { Name = nameField, ID = nameField, @class = "form-control", placeholder = Model.SwotTypeId.GetLabel() })

尝试:

<textarea name="swots[x1].swotParts[x2].label" class="form-control" placeholder="@Model.SwotTypeId.GetLabel()" >@Model.Label</textarea>

不要忘记用数字替换x1和x2。

您可以在此处阅读有关模型绑定到集合的更多信息。

http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx