4

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

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

这似乎可以通过设置 System.Web.Mvc.ModelMetadataProviders.Current为我自己的 CustomMetaDataProvider 来完成,但这还不足以涵盖上述所有三点。

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

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

我发现的唯一解决方案非常笨拙,需要从 System.Web.Mvc 子类化许多类型才能使其工作。我什至不得不完全重新实现CustomModelBinderDictionary,只覆盖一两行代码。所以它可以工作,但它是一个非常混乱的 hack,并且可能会在我下次更新到新的 ASP.NET MVC 版本时中断。

所以这就是我想知道的:我错过了任何简单的方法吗?

额外的问题:如果不是并且您来自 MVC 团队,您是否可以考虑在 MVC 4 中创建一个适当的可扩展点;-)?

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

4

2 回答 2

1

根据Brad Wilson(ASP.NET MVC 团队成员)的说法,这个问题已被列入 MVC 4 的错误列表。所以目前似乎没有好的解决方案,但希望当 MVC 4 出来时这个问题会得到解决。

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

于 2011-04-29T08:49:07.260 回答
0

我不确定您尝试使用 Validation、ModelBinding 和可能的 ModelMetadata 的自定义实现来做什么,而 MVC 中的 DependencyResolver 功能无法做到这一点?

最近 MVC 3 的 Tooling Update 中新的脚手架支持可能会满足您对脚手架的需求;但是,我会看一下是否可以连接到 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 实现和脚手架问题的需要。如果我假设不想用自己的元数据创建这么多 ViewModel 是正确的,那么这就是导致您尝试找到自定义 BindAttribute、自定义脚手架、自定义 ModelMetadata、自定义验证和自定义 ModelBinding 的实现的原因......

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

于 2011-04-26T19:22:45.730 回答