我已经看到类似的问题,并遵循常规答案,即确保所有模型数据都在HTML中呈现。
我已经完成了这个并且模型在@ Html.HiddenFor()的视图中呈现,但是当回发到控制器时,列表中没有项目?
视图将很乐意在列表中呈现多个项目,但发布数据中的List<Item> Items
始终为空列表(不为空)
模型
public class ItemCollection
{
public List<string> AvailiableActions { get; set; }
public List<Item> Items { get; set; }
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public string SelectedAction { get; set; }
}
查看
@model ItemCollection
@using (Html.BeginForm("myAction", "myController", FormMethod.Post))
{
<fieldset>
<div>
@Html.HiddenFor(m => Model.Items)
@Html.DisplayNameFor(x => x.AvailiableActions)
<table>
@{
foreach (var item in Model.Items)
{
@Html.HiddenFor(m => item)
@Html.HiddenFor(s => item.Id)
<tr>
<td>@item.Name</td>
<td>@Html.DropDownList(item.SelectedAction, new SelectList(Model.AvailiableActions))</td>
</tr>
}
}
</table>
</div>
</fieldset>
}
控制器
[HttpPost]
private ActionResult myAction(ItemCollection model)
{
if (model.Items.Count() == 0)
{
// this is true.. something is wrong......
}
}
答案 0 :(得分:1)
您不能使用foreach
循环来渲染集合的控件。它呈现重复的id
和name
属性,而没有必要的索引器来绑定到集合。使用for
循环
for (int i = 0; i < Model.Items.Count; i++)
{
<tr>
<td>
@Html.HiddenFor(m => m.Items[i].Id)
@Html.DisplayFor(m => m.Items[i].Name)
</td>
<td>@Html.DropDownList(m => m.Items[i].SelectedAction, new SelectList(Model.AvailiableActions))</td>
</tr>
}
请注意,您的视图还包括@Html.HiddenFor(m => Model.Items)
和@Html.HiddenFor(m => item)
,它们也会失败,因为item
是一个复杂的对象,您只能绑定到值类型。你需要删除它们。
答案 1 :(得分:1)
您可以考虑使用 EditorTemplates (an example on an other site),而不是迭代所有项目以确保将索引添加到生成的输出中。
EditorTemplates 允许您为Item
中的单个\Views\Shared\EditorTemplates\Item.cshtml
指定模板:
@model Item
@{
var options= (List<string>)ViewData["Options"];
}
<tr>
<td>
@Html.HiddenFor(m => m.Id)
@Html.DisplayFor(m => m.Name)
</td>
<td>@Html.DropDownList(m => m.SelectedAction, new SelectList(options))</td>
</tr>
然后您可以将视图更改为:
@model ItemCollection
@using (Html.BeginForm("myAction", "myController", FormMethod.Post))
{
<fieldset>
<div>
<table>
@Html.EditorFor(m => m.Items, new {Options = Model.AvailiableActions })
</table>
</div>
</fieldset>
}