快速业务通道

ASP.NET MVC 2:实体外部元数据扩展

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-05-20

在MVC的Model中,我们可以定义很多与视图相关的元数据,这些元数据对我们开发视图起着相当重要 的作用,特别是在数据验证方面。这些元数据一般情况下我们是不会定义在业务实体(或持久化实体)上 面,所以很多情况下,我们会需要开发两种实体:View Model和Business Model。这样就造成,在Action 与View的沟通当中,我们需要使用View Model,然后在业务逻辑处理时,我们需要再将View Model映射到 Business Model,这将会使我们的开发框架变得繁琐。因为一般情况下,View Model和Business Model在 很多情况下,都是很雷同的对象,只是View Model会有很多与视图相关的元数据。在这种情况下,只要我 们能把View Model作为Business Model的元数据描述对象(MetadataType)来使用,而不直接参与Action与 View的沟通,让这些工作都由Business Model来承担,这样就可以有效的避免很多重复工作。

在System.ComponentModel.DataAnnotations内部,提供了MetadataTypeAttribute这个标签,让我们 可以为Business Model指定它对应的视图元数据类型。特别是当我们使用LINQ2SQL、EF等框架来生成实体 框架时,我们可以以partial类的形式来提供它对应的视图元数据类型:

1 [MetadataType(typeof(Product_Metadata))]
2 public partial class Product 
3 {}
4
5 public class Product_Metadata
6 {
7 }

这样做在大多数情况下是没有问题的。但是仅仅是这样,还不能解决所有问题。一般情况下Business Model和MetadataType是不在同一个Assembly里面,这时候你就无法以partial类的形式来扩展Business Model。所以我们就需要有一套机制来延迟注册Business Model与MetadataType的映射关系。通过MVC源码 的分析,我们可以通过扩展 DataAnnotationsModelMetadataProvider的GetTypeDescriptor方法来解决这 个问题。

首先,我们先定义一个Business Model与MetadataType的映射容器:

01 public static class TypeDescriptorHelper
02 {
03     static Hashtable hashtable = new Hashtable();
04     static ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
05     static TypeDescriptorHelper()
06     {
07
08     }
09     public static void RegisterMetadataType(Type type, Type metadataType)
10     {
11         locker.EnterWriteLock();
12
13         hashtable[type] = metadataType;
14
15         locker.ExitWriteLock();
16     }
17     public static ICustomTypeDescriptor Get(Type type)
18     {
19         locker.EnterReadLock();
20         var metadataType = hashtable[type] as Type;
21         ICustomTypeDescriptor descriptor = null;
22         if (metadataType != null)
23         {
24             descriptor = new  AssociatedMetadataTypeTypeDescriptionProvider(type, metadataType).GetTypeDescriptor (type);
25         }
26         locker.ExitReadLock();
27         return descriptor;
28     }
29 }

这个容器非常简单,我们只是定义了一个hashtable来保存它们的映射关系。然后,我们从 DataAnnotationsModelMetadataProvider继承一个新的类,重写GetTypeDescriptor方法:

01 public class CustomDataAnnotationsModelMetadataProvider :  DataAnnotationsModelMetadataProvider
02 {
03     protected override System.Componen

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号