如何在ASP.NET MVC中提供自己的ICustomTypeDescriptor?

问题描述 投票:4回答:2

我正在为ASP.NET MVC 3开发一个小型库,该库可以提供更好的模型元数据可重用性,并且可以轻松地从数据实体映射到自定义视图模型。为此,我需要能够为ASP.NET MVC中三个不同的感兴趣区域提供我自己的ICustomTypeDescriptor实现:

  1. 脚手架
  2. 验证
  3. 模型绑定

看起来这可以通过将System.Web.Mvc.ModelMetadataProviders.Current设置为我自己的CustomMetaDataProvider来完成,但这还不足以覆盖上面的所有三点。

问题是System.Web.Mvc中有几个类直接调用这个不可扩展的System.Web.TypeDescriptorHelper,因为它看起来像这样:

internal static class TypeDescriptorHelper {
        public static ICustomTypeDescriptor Get(Type type) {
            return new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
        }
    } 

我找到的唯一解决方案非常笨拙,并且需要从System.Web.Mvc中继承许多类型以使其工作。我甚至不得不完全重新实现CustomModelBinderDictionary只是为了覆盖一行或两行代码。所以它有效,但它是一个非常混乱的黑客,并可能在下次更新到新的ASP.NET MVC版本时中断。

所以这就是我想知道的:我是否想念任何简单的方法?

奖金问题:如果没有,你来自MVC团队,你能考虑在MVC 4中创建一个合适的扩展点;-)?

编辑:回答问题为什么我需要编写自己的TypeDescriptor:有几个原因:1。最重要的是:我需要针对https://forums.asp.net/t/1614439.aspx/1 2中描述的问题的解决方法。另外,我需要为各种动态插入元数据原因。例如,我想编写自己的Bind属性,但BindAttribute是密封的。因此,在检测我自己的绑定属性实现时,我会从TypeDescriptor动态地发出匹配的BindAttribute,而不是从它派生。

asp.net-mvc validation modelbinders scaffolding modelmetadata
2个回答
1
投票

根据Brad Wilson(ASP.NET MVC团队成员)的说法,这个问题已被列入MVC 4的错误列表中。因此目前似乎没有好的解决方案,但希望这可以在MVC 4发布时解决。

对于任何对我的库感兴趣的可重用验证和脚手架元数据以及模型/视图模型映射的人,请随时在https://devermind.wordpress.com/订阅我的博客。我要在那里发布图书馆。


0
投票

我不确定你试图用Validation,ModelBinding和可能的ModelMetadata的自定义实现做什么,这是用MVC中的DependencyResolver功能无法完成的?

最近的MVC 3工具更新中的新脚手架支持可满足您对脚手架的需求;但是,我会看一下可能挂钩到ModelBinding,ModelMetadata和Validation的DependencyResolver功能,看看它们是否能达到你想要的效果。最近我遇到了类似的情况,我需要从头开始实现很多这些行为以提供灵活的框架,而我只能使用IoC的ModelMetadata和Validation提供程序来实现这一点。我还最终在少数情况下继承了DynamicObject(或ExpandoObject),以提供更大的灵活性。我知道这不是一个直接的答案,但我不确定为什么你需要访问低于这些可扩展性点的任何东西?

编辑:如果您希望在类似的ViewModel上重用ModelMetadata以避免在多个位置重新定义相同的ModelMetadata,您可能需要考虑这一点的含义。很多时候,您希望对实体进行某些数据限制,但这些限制应该在DataModel而不是ViewModel上。用户可能具有稍微更严格的规则。例如,您可以规定ViewModel中的某些字段对于用户是只读的,但是用作DataModel的实体允许您修改该值(通常在您的代码中)。类似地,您可能遇到用于生成VideModel的Create视图的ModelMetadata可能与用于Edit视图的ViewModel略有不同的情况。重用它们似乎是保持一致性和减少代码重复的好方法,但它可能是您后来后悔的事情。我最近遇到了同样的问题,我想避免为可能导致回发的每个视图编写一个新的ViewModel,我还没有找到一个我喜欢的完美解决方案,但我认为重用ModelMetadata会导致更多可能解决的问题。我的看法。为需要它们的视图编写ViewModel也可能无需实现自定义BindAttribute实现和Scaffolding问题。如果我正确地假设不想用自己的元数据创建如此多的ViewModel,那么是什么导致您尝试查找自定义BindAttribute,自定义Scaffolding,自定义ModelMetadata,自定义验证和自定义ModelBinding的实现...它可能是值得的看看创建ViewModel实际需要多长时间。

如果您找到更好的方法,请随时告诉我:-)

© www.soinside.com 2019 - 2024. All rights reserved.