【发布时间】:2013-08-22 16:17:44
【问题描述】:
我在发布包含字典的表单时遇到问题,该字典包含一个 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 足够聪明,可以在视图上呈现这个复杂对象的字段,但不够聪明,无法在我们回发时将它们收集回视图模型。
我发现this other guy 在这里遇到了类似的问题,他通过不使用字典而是创建一个复杂对象来解决它。但是,我想知道是否有更快的方法不需要我重写整个系统。
有什么想法吗?
更新
我通过获取 DefaultModelBinder 的源代码并对其进行调整来解决它。 我找到了来源here。我没有创建自己的 Binder,因为我希望所有高级功能和验证规则都适用于所有其他元素。 一旦我得到 DefaultModelBinder 编译和工作,我发现字典无法转换复杂项目的部分并编写了一个自定义字典更新方法来解决问题
【问题讨论】:
-
您可以发布您的更改吗?
标签: c#-4.0 asp.net-mvc-4 dictionary postback .net