绑定包含MVC4中列表的字典

时间:2013-08-20 14:43:53

标签: c#-4.0 asp.net-mvc-4 dictionary postback .net

我无法发布包含字典的表单,该字典包含一个int作为键,一个对象列表作为值。

最初这只是一个对象列表,工作正常,类型是:

List<MyObject> Fields

工作标记是

Fields_{0}__Property1

其中{0}是对象的索引。为了让它回发对象列表,我用这样的隐藏字段渲染了对象:

  @Html.HiddenFor(m => m.Property1, new { Name = string.Format("Fields[{0}].Property1", Model.Index), @id = string.Format("Fields_{0}__Property1", Model.Index) })

这很好用。然而,现在我们有一个字典而不是列表,列表在字典中。

现在的类型是:

Dictionary<int, List<MyObject>>.

我在使用Html.HiddenFor渲染字典时测试了预期的格式,因此我添加了具有所需格式的隐藏字段,现在是:

  @Html.HiddenFor(m => m.Property1, new { Name = string.Format("Fields[{0}][{1}].Property1", Model.Index, Model.Position), @id = string.Format("Fields_{0}__{1}__Property1", Model.Index, Model.Position) })

现在字段ID是

Fields_{0}__{1}__Property1

其中{0}是字典的键,{1}是列表中对象的索引。

然而,在回发中,我现在得到了

 [InvalidCastException: Specified cast is not valid.]
   System.Web.Mvc.CollectionHelpers.ReplaceDictionaryImpl(IDictionary`2 dictionary, IEnumerable`1 newContents) +131

我猜MVC非常聪明,可以在视图上渲染这个复杂对象的字段,但是当我们回发时,它们还不够聪明,无法将它们收回到viewmodel中。

我发现this other guy在这里遇到了类似的问题,他通过不使用字典解决了问题,而是创建了一个复杂的对象。但是,我想知道是否有更快的方法不需要我重写整个系统。

有什么想法吗?


更新

我通过获取DefaultModelBinder的源代码并进行调整来解决它。 我找到了来源here。我没有创建自己的Binder,因为我希望所有高级功能和验证规则适用于所有其他元素。 一旦我得到DefaultModelBinder编译和工作,我发现字典无法转换复杂项目的部分,并编写了一个解决问题的自定义字典更新方法

1 个答案:

答案 0 :(得分:1)

您始终可以创建自定义模型绑定器,以根据需要从请求值绑定对象。只需创建一个实现System.Web.Mvc.IModelBinder接口的类并实现BindModel()方法。