我有看法:
@using (Html.BeginForm("ProcessRoute", "Calculator"))
{
@Html.TextBox("CityArrival", null, new { @style = "width: 300px;" })
@Html.TextBox("CityDeparture", null, new { @style = "width: 300px;" })
@{ Html.RenderPartial("BusModelList", @Model.BusModels); }
<input id="submit" type="submit" value="Поиск" />
}
局部视图:
@model List<ViewModels.GroupedBusModelsSelectable>
<table>
@foreach (var item in Model)
{
<tr>
<td colspan="3" align="left">@item.BusType.Name</td>
</tr>
foreach (var bus in item.BusModels.OrderBy(c => c.Bus.NumPlaces).ToList())
{
@Html.EditorFor(x=>bus);
}
}
</table>
和编辑:
@model ViewModels.BusModelSelectable
<tr>
<td>
@Html.HiddenFor(x => x.Bus.Id)
@Html.HiddenFor(x => x.Bus.FullName)
@Html.CheckBoxFor(x => x.IsSelected)
</td>
<td>
<img>
<td>
@Model.Bus.FullName
</td>
</tr>
现在我想在控制器上获取所有busModel(已选中):
[HttpPost]
public ActionResult ProcessRoute(string CityArrival, string CityDeparture, IEnumerable<GroupedBusModelsSelectable> BusModels)
由于某种原因,BusModels为空
在HttpContext.Request.Form
我看到(bus.IsSelected,bus.Bus.Id)的列表。我怎样才能在控制器上获得它?
决策
在Nick Larsen的建议之后,我明白我应该在我的html上编入索引名称。因为我有两个级别的集合,所以我应该两次。
PartialView:
@model List<Avtobus66.ViewModels.GroupedBusModelsSelectable>
<table>
@for (int j = 0; j < Model.Count(); j++)
{
<tr>
<td colspan="3" align="left">@Model[j].BusType.Name</td>
</tr>
for (int i = 0; i < Model[j].BusModels.Count(); i++)
{
@Html.EditorFor(x => Model[j].BusModels[i]);
}
}
</table>
现在让我们看看html:
<input name="[0].BusModels[0].Bus.Id" type="hidden" value="1" />
<input name="[0].BusModels[0].IsSelected" type="checkbox" value="true" />
<input name="[0].BusModels[0].IsSelected" type="hidden" value="false" />
<input name="[0].BusModels[1].Bus.Id" type="hidden" value="2" />
<input name="[0].BusModels[1].IsSelected" type="checkbox" value="true" />
<input name="[0].BusModels[1].IsSelected" type="hidden" value="false" />
<input name="[0].BusModels[2].Bus.Id" type="hidden" value="3" />
<input name="[0].BusModels[2].IsSelected" type="checkbox" value="true" />
<input name="[0].BusModels[2].IsSelected" type="hidden" value="false" />
<input name="[1].BusModels[0].Bus.Id" type="hidden" value="4" />
<input name="[1].BusModels[0].IsSelected" type="checkbox" value="true" />
<input name="[1].BusModels[0].IsSelected" type="hidden" value="false" />
在控制器上,我现在准备好获得2级收集。在我的情况下
IEnumerable<GroupedBusModelsSelectable> BusModels
它有效。现在我同意尼克,我应该重构我的桌面标记意大利面。
答案 0 :(得分:2)
您需要查看发送到浏览器的内容。为了填充BusModels
参数,您需要向浏览器发送类似:
<input type="hidden" name="BusModels[0].someProperty" value="whatever" />
<input type="hidden" name="BusModels[0].someOtherProperty" value="whatever" />
<input type="checkbox" name="BusModels[0].someBoolean" />
<input type="hidden" name="BusModels[1].someProperty" value="whatever" />
<input type="hidden" name="BusModels[1].someOtherProperty" value="whatever" />
<input type="checkbox" name="BusModels[1].someBoolean" />
请注意,名称中唯一更改的是方括号内的值。还有其他方法可以执行此操作,但它们都是此方法的变体,您可以找到有关它们的更多信息here。由于您没有列出动态添加新元素的控件,我建议将编辑器重写为模板并使用内置功能构建输入。
要实现此目的,请将模型传递给已排序的局部视图,然后使用普通foreach
循环并调用编辑器来代替模型的索引,而不是使用for
。
查看:
@using (Html.BeginForm("ProcessRoute", "Calculator"))
{
@Html.TextBox("CityArrival", null, new { @style = "width: 300px;" })
@Html.TextBox("CityDeparture", null, new { @style = "width: 300px;" })
@{ Html.RenderPartial("BusModelList", Model.BusModels.OrderBy(c => c.Bus.NumPlaces).ToList()); }
<input id="submit" type="submit" value="Поиск" />
}
部分视图:
@model List<ViewModels.GroupedBusModelsSelectable>
<table>
@foreach (var item in Model)
{
<tr>
<td colspan="3" align="left">@item.BusType.Name</td>
</tr>
for (int i = 0; i < Model.Count; i++)
{
@Html.EditorFor(x => x[i]);
}
}
</table>
这应该可以解决问题。除此之外我唯一提到的是你将表格和表格的行分开,这会在视图和局部视图之间产生紧密耦合。处理此问题的更好方法是删除耦合并将所有相关构造放在同一位置。最简单,最干净的方法是使用剃刀内联模板,或完全离开表格,因为语义编辑器不是表格数据。