Asp.Net MVC绑定。在控制器</model>获取列表<model>

时间:2011-06-01 15:54:29

标签: asp.net-mvc binding partial-views

我有看法:

    @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

它有效。现在我同意尼克,我应该重构我的桌面标记意大利面。

1 个答案:

答案 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>

这应该可以解决问题。除此之外我唯一提到的是你将表格和表格的行分开,这会在视图和局部视图之间产生紧密耦合。处理此问题的更好方法是删除耦合并将所有相关构造放在同一位置。最简单,最干净的方法是使用剃刀内联模板,或完全离开表格,因为语义编辑器不是表格数据。