【问题标题】:MVC3 ModelBinder for DynamicObject动态对象的 MVC3 模型绑定器
【发布时间】:2011-03-01 18:49:38
【问题描述】:

我正在寻找是否有示例项目、教程、contrib 分支或类似的详细信息为 MVC3 实现自定义 ModelBinder 以支持从 DynamicObject 继承的对象。

我有一个域对象,它具有由数据库定义的动态数量的属性,并且这些属性可以在运行时更改。为了使使用对象更容易,我让我的类实现继承自 DynamicObject 并通过 [dynamic] 关键字将模型传递给视图。

对象的所有动态属性都在对象的一个​​集合属性中,称为“属性”。我想创建一系列编辑器模板来充实模型,理想情况下,我所要做的就是按照 Html.EditorForModel() 的方式进行调用,它将动态构建 UI。

问题是我没有太多运气找到能够检查 DynamicObject 并搭建 UI 的 ModelBinder 的实现(我认为这是正确的术语吗?)。

我发现 IDictionary ModelBinder 项目是在 Roberto Hernandez (@hernandezrobert) 在 MVC3 Extensability(来源为 http://mvcextensibility.codeplex.com/)上完成的 MVCConf 视频之一中完成的,但我没有太多运气将其适应我的目的。我想知道是否有其他人试图创建一个能够做我所描述的模型活页夹?或者可以为我指明正确的方向?

【问题讨论】:

    标签: asp.net-mvc dynamic asp.net-mvc-3 modelbinders


    【解决方案1】:

    ModelBinders 不帮助生成视图,它们帮助将来自各种 Web 源(表单、查询字符串等)的原始参数映射到您的操作方法所期望的输入参数(特别是,如果您的输入参数是某种类型的类而不是原语)。

    您正在寻找的是如何生成视图模板的示例,我还没有看到动态。到目前为止,我见过的用于生成常规视图模板的最佳资源是 Brad Wilson's blog。如果您有办法(听起来像您这样做)弄清楚对象必须显示哪些属性以及关于如何显示它们的元数据(例如 textarea 与 input type=text 等),那么您应该能够跟着布拉德一起走。

    【讨论】:

    • 听起来它可能有效,但在将数据发回控制器时,我仍然需要 ModelBinder/MetaDataProvider 进行验证。
    • 是的,这就是模型绑定器的用武之地。如果您的自定义动态对象只是将字符串字典作为工厂方法或在构造函数重载中使用对象,那么您的模型绑定器可以传递它可能是最简单的在。
    • 我认为ModelBinder实际上也用于构建视图。当我尝试使用 EditorForModel() 为视图自动构建 UI 时,它会正确生成字段,但是一旦我根据上面提到的可扩展性项目注册自定义 ModelBinder,EditorForModel() 就会按预期停止工作。也许它在你使用 EditorForModel() 或 EditorFor() 时使用?
    【解决方案2】:

    我能够通过设置一个普通类作为我的 DanamicObject 的模型来解决我的问题,并像这样存储我的属性

    IList<DynamicProperty> DynamicProperties { get; set; }
    

    我为 DynamicObject 创建了一个自定义视图,并在该视图中调用了其中一个助手来显示 DynamicProperties 属性。这让 MVC 可以遍历集合并呈现每个属性。接下来,我有一个 DynamicProperty 视图,用于根据需要呈现属性。关键是您还必须呈现包含该特定属性的主键的隐藏字段。 MVC3 中的 ModelBinder 在这里比 MVc2 做得更好,因此它将数组索引呈现为字段名称的一部分,以便每个属性的主键和值在提交时正确配对。您可能希望专门为提交的数据创建一个 ViewModel,当我尝试使用在详细信息/编辑视图中使用的相同模型类时遇到问题,因为我只呈现了字段的子集,因此当我绑定到时它们丢失了回发时使用相同的 Model 类。

    您可以按照通常的方式处理保存,但是对于这种类型的对象,有一些安全方面的考虑。因为属性的数量是动态的,所以无法确保提交的字段数量与最初呈现的数量相同。用户可以注入他们自己的,或者更糟的是为您可能已明确排除的属性添加字段。 AntiForgeryToken 将防止此类提交发生在您的域之外,但由于 jQuery 等库提供的 DOM 操作的易用性和流行性,跨站点回发并不是唯一的问题,我不知道 AntiForgeryToken 是否会考虑这个,但我对此表示怀疑。

    事实证明,这种方法比尝试从 DynamicObject 继承、实现 GetDynamicMemberNames 并制作自定义 ModelBinder 以使用环绕它更容易。

    然而,我确实创建了一个自定义 ModelMetaData 和 Validation Provider 来处理这些方面,因为属性不是强类型的,所以 MVC 没有任何注释可以使用。

    【讨论】:

      猜你喜欢
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      • 2014-12-29
      相关资源
      最近更新 更多