ASP.NET MVC 透過 ModelMetadataProvider 抽象類別提供模型中繼資料,預設使用 CachedDataAnnotationsModelMetadataProvider(快取版)委派給 DataAnnotationsModelMetadataProvider 解析 DataAnnotations 特性。本文詳細說明提供者層級架構與擴展點。
public abstract class ModelMetadataProvider
{
public abstract IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType);
public abstract ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);
public abstract ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);
}
public static class ModelMetadataProviders
{
public static ModelMetadataProvider Current { get; set; }
}
public abstract class AssociatedMetadataProvider : ModelMetadataProvider
{
protected abstract ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName);
// 實現三個抽象方法:反射取得特性 → 呼叫 CreateMetadata → 篩選 IMetadataAware 特性呼叫 OnMetadataCreated
}
核心流程:收集目標類型/屬性上的所有特性 → 呼叫 CreateMetadata 建立 ModelMetadata → 找出實作 IMetadataAware 的特性並呼叫 OnMetadataCreated 允許進一步客製化。
public class DataAnnotationsModelMetadataProvider : AssociatedMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
// 解析 DataAnnotations 特性(Display、Required、StringLength、DataType 等)初始化 ModelMetadata 屬性
}
}

預設採用 CachedDataAnnotationsModelMetadataProvider 包裝以提升效能,最終仍由 DataAnnotationsModelMetadataProvider 執行核心解析邏輯。