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 使用句点或下划线而不是方括号来分隔集合索引,例如&lt;input name="Lines.0.Name" /&gt;?


注意:我正在使用这个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 方括号集合模型绑定的主要内容,如果未能解决你的问题,请参考以下文章

asp.net mvc 4,模型绑定改变了线程?

ASP.NET MVC 正则表达式属性不适用于括号(文字)

ASP.NET MVC

[转] ASP.NET MVC 模型绑定的功能和问题

ASP.NET MVC学习之模型绑定

ASP.NET MVC 4 模型绑定