ModelMetadataProvider重写MetadataTypeAttribute的替代方法

时间:2013-08-05 10:21:34

标签: c# asp.net-mvc asp.net-mvc-4 reflection

在使用Asp.Net MVC一段时间后,我决定在项目中实际使用它。出现的问题之一是前端站点可能对给定模型具有与管理面板不同的验证规则。

我知道MetadataType属性,但由于你有多个上下文,这对我们开箱即用。

为了解决这个问题,我实现了一个自定义的ModelMetadataProvider,它根据请求的执行上下文将默认的ModelMetdataProvider重定向到不同的类型。这非常适合显示所需的UI。

我不喜欢这个解决方案的一部分是我最终从我的自定义模型元数据提供程序中读取堆栈,以确定给定的调用是否用于模型绑定。这是因为当我没有这样做时,我会在从Controller调用TryUpdateModel期间正确地得到“对象与目标类型不匹配”,因为模型绑定器试图使用类型A中的属性将值设置为类型B的实例

读取调用堆栈对生产这么糟糕吗? 有没有办法在不使用属性的情况下有选择地复制MetadataTypeAttribute行为?

提前致谢,

约翰

2 个答案:

答案 0 :(得分:0)

这是你希望ASP.NET MVC团队没有密封一个类的那些实例之一 - 我确信他们有他们的理由。我打算建议简单地创建自己的属性,派生自MetadataTypeAttribute。

解决这个问题的一种方法是获取属性的来源并编写自己的:

http://dotnetinside.com/framework/v4.0.30319/framework/v4.0.30319/System.ComponentModel.DataAnnotations/MetadataTypeAttribute

当然,这会使您的代码难以维护。

我会断言,据我所知,您已经使用ModelMetadataProvider作为解决方案做出了正确的决定。关于分析调用堆栈,改变位置,将某些东西移动到某个区域,我对你有点紧张。你得到了我的漂移,即用构建时决定来破解代码是非常容易的,这个决定在运行时或QA之后都找不到。

你还没有提供如何粗略确定上下文,但我个人会通过向Enum(有限的可能性和设计时间断裂)添加一个属性来解决这个问题,其中包含可能的上下文列表,然后在旋转期间该类的填充,填充它,准备执行Provider,它将根据Enum的值传递正确的metatdatatype。

很多方法可以为这只猫提供皮肤,但是在构建时会破坏的东西会为你提供最好的服务,恕我直言。

答案 1 :(得分:0)

除非您使用MVC 6,否则您可能会发现ModelMetadata Fluent Configuration非常有用。

可以找到一些如何使用它的好例子herehere

真正重要的是,它只是完全由您控制的代码。因此,一旦您有不同的上下文,您可能决定定义不同的配置,或者您可能会更加努力地为不同的上下文制作(一组)不同的注册

真正有用的是"装饰" (有意使用的术语!)基类的属性,至少似乎没有任何东西可以让你这样做。

编辑:模型元数据不应该WCF RIA Services Contrib混淆。