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>
无论如何,当我提交表单时,部分视图中的值永远不会到达控制器。
您有什么想法如何正确映射?
谢谢!
答案 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。
您可以在此处阅读有关模型绑定到集合的更多信息。