ASP.NET MVC 方括号集合模型绑定
Posted
技术标签:
【中文标题】ASP.NET MVC 方括号集合模型绑定【英文标题】:ASP.NET MVC Square Bracket Collection Model Binding 【发布时间】:2012-09-13 21:02:21 【问题描述】:ASP.NET MVC 的集合模型绑定需要 <input />
名称属性中的方括号索引才能正确绑定集合模型,例如<input name="Lines[0].Name" />
的操作如下:
public ActionResult Create(IEnumerable<MyInputModel> Lines)
// ...
但是,对于某些 jQuery 插件,名称属性中的句点和方括号是 known issue,包括我正在使用的 Select2 列表选择器。
由于我不想破解 Select2,我如何告诉 ASP.NET MVC 使用句点或下划线而不是方括号来分隔集合索引,例如<input name="Lines.0.Name" />
?
注意:我正在使用这个collection model binding technique 来生成非顺序的Guid
索引,所以我已经声明了一个自定义htmlFieldPrefixScope
。
更新:我通过破解 Select2 事件中的自定义滚动/调整大小事件名称解决了这个问题,这些事件将无效的 [
或 ]
字符传递给 bind
/unbind
jQuery 方法。
【问题讨论】:
【参考方案1】:public ActionResult Create(List<MyInputModel> Lines)
// ...
<input name="Lines[0].Name" />
确保输入名称与列表名称相同且索引以 0 开头。
对不起,我想念明白。试试这个方法。
@foreach (var item in Model)
var name = string.Format("Lines[0].name", i);
<input type="text" name="@name" value="@item.name" />
【讨论】:
这根本没有解决我的问题。【参考方案2】:您真的需要实体列表吗?因为如果没有,字符串列表就足够了,你可以跳过带索引的括号:like here
【讨论】:
每个项目都有多个属性。您提供的链接还使用方括号来索引项目。 是的,如果项目有多个属性(不仅仅是“名称”),您应该使用括号。这就是我问你问题的原因。但是如果根据上面的链接只是'name'属性,你可以这样写: 但据我了解,这不是您的解决方案……希望您能找到另一个解决方案。【参考方案3】:您无法自定义 DefaultModelBinder 来实现这一点。但是您可以使用自定义的FormValueProvider
,它将传入的前缀格式从List.0.Name
转换为List[0].Name
并返回值。
【讨论】:
谢谢,我想我可能需要编写一个自定义集合模型活页夹。你能指出我如何做到这一点的正确方向吗?一些示例代码会有很长的路要走。 创建自定义集合模型绑定器是一项复杂的工作,您可以理解,当您看到 DefaultModelBinder 的源代码并且其中一些方法是内部的或私有的,这让我们的生活变得复杂。 通过在 Select2 上进行黑客攻击修复了此问题。更新的问题。【参考方案4】:我不确定您是否可以将选择器更改为使用“id”属性而不是“名称”属性。如果是这样,MVC 中的集合绑定仍然有效,并且您将在 id 属性中拥有 jquery 安全值,您可以与 Select2 一起使用:
@for(int i=0; i<Lines.Count; i++)
<input name="@Html.FieldNameFor(m=>m.Name)" id="@Html.FieldIdFor(m => m.Name)" />
【讨论】:
以上是关于ASP.NET MVC 方括号集合模型绑定的主要内容,如果未能解决你的问题,请参考以下文章