获取控制器中已检查模型的列表
Get a list of checked models in controller
控制器:
[HttpPost]
public ActionResult GetChecked(FormCollection formCollection)
{
var checked = formCollection["Checked"].Split(',');
var ids = formCollection["Original.ID"].Split(',');
}
查看:
@model IEnumerable<Models.Entry> []
<table>
@using (Html.BeginForm("GetChecked", "ControllerName"))
{
@foreach (var item in Model[0])
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Original.ID)
@Html.HiddenFor(modelItem => item.Original.ID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Original.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.New.Name)
</td>
<td>
@Html.CheckBoxFor(modelItem => item.Checked)
</td>
</tr>
}
</table>
//Then there's another table with Model[1]
型号
public class Entry
{
public Entry()
{
Original = new SomeObject();
New = new SomeObject();
Checked = false;
}
public SomeObject Original { get; set; }
public SomeObject New { get; set; }
public bool Checked { get; set; }
}
这有效,但我的控制器中的 ids
-array 为选中的行同时获得了 true- 和 false 值。我读到这是因为 FormCollection
。
问题:如何让 GetChecked
取一个 IEnumerable<Models.Entry>
作为参数?当我尝试它时,它产生了一个空值。
结果为空,因为您应该将 IEnumerable 接口与模型绑定器绑定。我认为您正在寻求创建模型绑定提供程序,因为提供程序可以查看 属性 的类型,然后仅为该 属性.
创建自定义模型绑定程序
看看这个 link 还有 http://odetocode.com/blogs/scott/archive/2009/04/27/6-tips-for-asp-net-mvc-model-binding.aspx
有几处您应该更改:
当使用 CheckBoxFor、EditorFor 等从列表或数组呈现控件时,您应该 永远不要使用 foreach
- 相反,始终使用for
-loop 并将索引应用到您的 collection。原因是索引在您的 <form>
中创建了 编号的项目,然后它们不再相互冲突,而这些编号的项目正是您成功处理已提交列表所需要的值。请参阅此答案以获取一个简单示例:https://whosebug.com/a/15375949/1220550
不要使用 FormCollection
,而是使用 ViewModel class。通过使用 FormCollection
,您将放弃数据绑定/ModelState
/ValidationSummary
,它们一起是 ASP.NET MVC 的一个极好的特性。在这里解释一切太多了,但这里有一个 great link 可以做到这一点。
最好使用完全定义的 ViewModel class,不仅是为了数据绑定(见之前),也是为了一致性和 ease-of-use。将 IEnumerable<X>
的 array 作为 @model
充其量是令人困惑的,最坏的情况是导致错误的原因。如果你突然也想传递一个 int
怎么办?使用 IEnumerable<X>[]
是不可能的,但是使用 ViewModel 是小菜一碟 - 只需将其添加到 class.
控制器:
[HttpPost]
public ActionResult GetChecked(FormCollection formCollection)
{
var checked = formCollection["Checked"].Split(',');
var ids = formCollection["Original.ID"].Split(',');
}
查看:
@model IEnumerable<Models.Entry> []
<table>
@using (Html.BeginForm("GetChecked", "ControllerName"))
{
@foreach (var item in Model[0])
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Original.ID)
@Html.HiddenFor(modelItem => item.Original.ID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Original.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.New.Name)
</td>
<td>
@Html.CheckBoxFor(modelItem => item.Checked)
</td>
</tr>
}
</table>
//Then there's another table with Model[1]
型号
public class Entry
{
public Entry()
{
Original = new SomeObject();
New = new SomeObject();
Checked = false;
}
public SomeObject Original { get; set; }
public SomeObject New { get; set; }
public bool Checked { get; set; }
}
这有效,但我的控制器中的 ids
-array 为选中的行同时获得了 true- 和 false 值。我读到这是因为 FormCollection
。
问题:如何让 GetChecked
取一个 IEnumerable<Models.Entry>
作为参数?当我尝试它时,它产生了一个空值。
结果为空,因为您应该将 IEnumerable 接口与模型绑定器绑定。我认为您正在寻求创建模型绑定提供程序,因为提供程序可以查看 属性 的类型,然后仅为该 属性.
创建自定义模型绑定程序看看这个 link 还有 http://odetocode.com/blogs/scott/archive/2009/04/27/6-tips-for-asp-net-mvc-model-binding.aspx
有几处您应该更改:
当使用 CheckBoxFor、EditorFor 等从列表或数组呈现控件时,您应该 永远不要使用
foreach
- 相反,始终使用for
-loop 并将索引应用到您的 collection。原因是索引在您的<form>
中创建了 编号的项目,然后它们不再相互冲突,而这些编号的项目正是您成功处理已提交列表所需要的值。请参阅此答案以获取一个简单示例:https://whosebug.com/a/15375949/1220550不要使用
FormCollection
,而是使用 ViewModel class。通过使用FormCollection
,您将放弃数据绑定/ModelState
/ValidationSummary
,它们一起是 ASP.NET MVC 的一个极好的特性。在这里解释一切太多了,但这里有一个 great link 可以做到这一点。最好使用完全定义的 ViewModel class,不仅是为了数据绑定(见之前),也是为了一致性和 ease-of-use。将
IEnumerable<X>
的 array 作为@model
充其量是令人困惑的,最坏的情况是导致错误的原因。如果你突然也想传递一个int
怎么办?使用IEnumerable<X>[]
是不可能的,但是使用 ViewModel 是小菜一碟 - 只需将其添加到 class.