用于DynamicObject的MVC3 ModelBinder

时间:2011-03-01 18:49:39

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

我正在查看是否有一个示例项目,教程,contrib分支或类似的内容,详细说明了为MVC3实现自定义ModelBinder以支持从DynamicObject继承的对象。

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

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

问题是我找不到能够检查DynamicObject和构建UI的ModelBinder的实现并不是很幸运(我认为这是正确的术语吗?)。

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

2 个答案:

答案 0 :(得分:3)

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

您正在寻找的是一个如何生成视图模板的示例,我没有看到它的动态。到目前为止,我见过的常规视图模板生成的最佳资源是Brad Wilson's blog。如果您有一个方法(听起来像你这样做)确定对象必须显示哪些属性w /元数据有关如何显示它们(例如textarea与输入类型=文本等),那么你应该能够跟随布拉德一起走。

答案 1 :(得分:1)

我能够通过设置一个普通的类来作为我的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没有任何注释可供使用。