2017-03-08 46 views
1

你好,Mighty Stackoverflowers,ASP.NET MVC 4.5地图部分视图到窗体上的主视图提交

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

在我看来“Create.cshtml”我称之为局部视图“_SwotPart.cshtml”。我通过我的视图模型的一部分,以局部视图,类似这样的:

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> 

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

你有任何想法如何正确映射这个吗?

谢谢!

回答

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]) 
     } 
    } 

    ... 

然后,局部有正确的情况下继续努力,你的输入将被命名为喜欢Swots[0].SwotParts[0].Label,该模型绑定器会能够工作。

但是,这里需要注意的是,你将这个列表分成两个循环。这还没有起作用,因为您正在有效地解决模型中项目位置的总体上下文。为了解决这个问题,你应该在你的模型,这是更好的,反正拆你的列表,你可以从您的视图中删除此业务逻辑:

public class SwotVm 
{ 
    ... 

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

然后,您可以简单地在每个列表迭代单独和值自然会回到适当的清单。

鉴于您正在使用partial来渲染特定类类型的字段,不过,您最好通过创建编辑器模板来提供服务。如果你只是你的部分代码移到视图: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声明。

+0

感谢克里斯对这个伟大而详细的解释! – TimHorton

0

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

SWOTS [X1] .swotParts [X2] .label

其中X 1是一个数字范围从0并且至多为每个SWOT。 其中,对于swot中的每个swot部分,x2是从0到上的数字。

现在,当您发布时,表单数据名称仅为标签

相反的:

@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

+0

感谢您的帮助和好主意! – TimHorton