【问题标题】:Two-way bind Dictionary<string, byte> in MVC viewMVC 视图中的双向绑定 Dictionary<string, byte>
【发布时间】:2011-03-17 03:07:28
【问题描述】:

我的模型中有两个 Dictionary&lt;string, byte&gt; 属性,应该使用 0 到 5 个项目正确验证。例如属性skill (string dropDownListLabel, byte years)

因为我需要支持非javascript客户端,所以我将所有5个输入对渲染到浏览器,只绑定现有的字典项,生活很棒。这为一个新的纯 HTML 表单提供了 5 个空输入对,每个输入对都有唯一的输入名称,这也是我想要的。

这是我使用的序列化(输入名称):

skill[0].Key = "", skill[0].Value = ""
 ... three more pairs ...
skill[4].Key = "", skill[4].Value = ""

但是在 POST 上,对于既没有指定 Key 也没有指定 Value 的 Key/Value 对,Value 上会出现 DefaultModelBinder 验证错误。

bothneither Key 和 Value 都被 POST 时,我是否可以使用类型和序列化在 DefaultModelBinder 中进行验证,因此 MVC 为我做的工作与可能,只有当它们有内容时才将它们添加到集合中?

谢谢, 香农

【问题讨论】:

  • 我遵循了 Darin 在下面接受的答案的后半部分。我用空值预饱和 List,其中 T 实现 IValidatable 以确保两者或都不提供任何值。此外,我在 T 上使用静态方法将 List 转换为相应的 IEnumerable 或从相应的 IEnumerable 转换,作为存储饱和/脱水过程的方便位置。最后,我还将唯一性比较放在那里,并从顶层模型上的 IValidatable 调用它。这也解决了 MVC 没有为字典项使用配置的 DataAnnotationValidation “Value Required”消息的问题。

标签: asp.net-mvc data-binding viewmodel


【解决方案1】:

您不能将空字符串绑定到值类型 (byte),因此默认模型绑定器会将您的模型标记为无效。如果你想允许空值,你应该使用一个可为空的字节:

Dictionary<string, byte?>

更新:

另一种可能性是使用包含两个属性的自定义类型的集合,每个属性分别代表键和值。然后在您的视图中使用强类型帮助器和编辑器模板,这样您就不必担心有线格式,最后您需要确保键是唯一的,因此您需要一个自定义验证器。我个人在这部分使用FluentValidation.NET,但如果您使用数据注释,您将需要一个自定义属性,用于装饰视图模型中的集合属性。

【讨论】:

  • 这是我想要的相反行为,创建空字典项。并且不能有 5 个相同的空字符串绑定到 Key。如果 Key 和 Value 都是空字符串,我根本不希望它绑定该项目。绑定是通过枚举 Model 属性而不是通过表单值来实现的,对吗?所以我认为可能还有另一种数据类型可以按我想要的方式工作。如果设置了一个值而不设置另一个值,或者发布了重复的字符串,我只想要一个验证错误。
  • 如果这是一个仅限 AJAX 的页面,我只会发布带有内容的对,而 Dictionary 就可以了。它不仅仅是 AJAX,所以我想知道最佳实践是什么。
  • @shannon,绑定是根据请求中发送的任何值发生的。因此,如果您发送空值,默认模型绑定器将尝试绑定它们。显然,您不能在字典中使用相同的键,这首先与字典的内容相矛盾。所以在这种情况下,最好的做法是使用一些自定义视图模型而不是字典。
  • @Darin:对,完全有道理。考虑到我希望有可变数量的具有强制性关联值的唯一键,对模型结构、线路格式和验证过程有什么建议吗?同样,我只想编写最少的代码并充分利用 MVC。我看到自己在不久的将来会再次遇到这种需求。
  • @shannon,您可以使用自定义类型的集合,其中包含两个属性,每个属性分别代表键和值。然后在您的视图中使用强类型帮助器和编辑器模板,这样您就不必担心有线格式,最后您需要确保键是唯一的,因此您需要一个自定义验证器。我个人在这部分使用FluentValidation.NET,但如果您使用数据注释,您将需要一个自定义属性,用于装饰视图模型中的集合属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 2019-01-29
  • 1970-01-01
  • 2015-07-10
  • 1970-01-01
相关资源
最近更新 更多