程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> ASP.NET MVC 2:實體外部元數據擴展

ASP.NET MVC 2:實體外部元數據擴展

編輯:關於ASP.NET

在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 }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved