【问题标题】:Binding a dictionary containing a list in MVC4在 MVC4 中绑定包含列表的字典
【发布时间】: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


【解决方案1】:

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

【讨论】:

  • 是的,尽管编写自定义对象可能比这要少得多
  • 可能是 6 of 1,我猜是其他场景的六种。您可以查看的另一件事是可以在操作方法及其参数上标记的属性,以便为默认模型绑定器提供更多信息。我知道的一个是Bind 属性,不确定是否还有其他属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-11
  • 2014-01-11
相关资源
最近更新 更多