min*_*ods 41 defaultmodelbinder modelbinders asp.net-mvc-3
MVC 3.0中的默认模型绑定器是否能够处理非顺序索引(对于简单和复杂模型类型)?我遇到的帖子表明应该这样做,但是在我的测试中它似乎没有.
给出后期值:
items[0].Id = 10
items[0].Name = "Some Item"
items[1].Id = 3
items[1].Name = "Some Item"
items[4].Id = 6
items[4].Name = "Some Item"
Run Code Online (Sandbox Code Playgroud)
和控制器方法:
public ActionResult(IList<MyItem> items) { ... }
Run Code Online (Sandbox Code Playgroud)
加载的唯一值是项0和1; 第4项被忽略了.
我已经看到了许多生成自定义索引的解决方案(模型绑定到列表),但是它们似乎都是针对MVC的早期版本,而且大多数都是有点"严厉"的IMO.
我错过了什么吗?
Bas*_*nni 70
我有这个工作,您必须记住添加一个常见的索引隐藏输入,如您引用的文章中所述:
隐藏的输入name = Items.Index是关键部分
<input type="hidden" name="Items.Index" value="0" />
<input type="text" name="Items[0].Name" value="someValue1" />
<input type="hidden" name="Items.Index" value="1" />
<input type="text" name="Items[1].Name" value="someValue2" />
<input type="hidden" name="Items.Index" value="3" />
<input type="text" name="Items[3].Name" value="someValue3" />
<input type="hidden" name="Items.Index" value="4" />
<input type="text" name="Items[4].Name" value="someValue4" />
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助
您引用的文章是一篇旧文章(MVC2),但据我所知,这仍然是使用默认模型绑定器对绑定集合进行建模的事实上的方法。
如果您想要非顺序索引,就像巴萨姆所说,您将需要指定一个索引器。索引器不需要是数字。
为此,我们使用Steve Sanderson 的 BeginCollectionItem Html Helper 。它会自动生成索引器作为 Guid。我认为当您的集合项 HTML 是非顺序的时,这是比使用数字索引器更好的方法。
这个辅助方法源于Steve Sanderson的方法,它更加简单,可用于锚定集合中的任何项目,它似乎与MVC模型绑定一起使用.
public static IHtmlString AnchorIndex(this HtmlHelper html)
{
var htmlFieldPrefix = html.ViewData.TemplateInfo.HtmlFieldPrefix;
var m = Regex.Match(htmlFieldPrefix, @"([\w]+)\[([\w]*)\]");
if (m.Success && m.Groups.Count == 3)
return
MvcHtmlString.Create(
string.Format(
"<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />",
m.Groups[1].Value, m.Groups[2].Value));
return null;
}
Run Code Online (Sandbox Code Playgroud)
例如,只需在EditorTemplate或您将生成输入的任何其他位置调用它,如下所示,以生成索引锚定隐藏变量(如果适用).
@model SomeViewModel
@Html.AnchorIndex()
@Html.TextBoxFor(m => m.Name)
... etc.
Run Code Online (Sandbox Code Playgroud)
我认为它比史蒂夫桑德森的方法有一些优势.
它适用于EditorFor和其他内置机制来处理枚举.因此,如果Items是IEnumerable<T>视图模型上的属性,则以下按预期工作:
<ul id="editorRows" class="list-unstyled">
@Html.EditorFor(m => m.Items)
@* Each item will correctly anchor allowing for dynamic add/deletion via Javascript *@
</ul>
它更简单,不需要任何魔术字符串.
对于数据类型,您可以使用单个EditorTemplate/DisplayTemplate,如果未在列表中的项目上使用,则它将只是无操作.
唯一的缺点是,如果绑定的根模型是可枚举的(即Action方法本身的参数,而不仅仅是参数对象图中更深处的属性),则绑定将在第一个非顺序索引处失败.不幸的是,.IndexDefaultModelBinder 的功能仅适用于非root对象.在这种情况下,您唯一的选择仍然是使用上述方法.