呼叫 HtmlHelper 模板方法(DisplayFor、EditorFor 等)時,MVC 依據 ModelMetadata 尋找對應模板。本文深入探討模板搜尋順序、DataTypeAttribute 與 UIHintAttribute 的關係與優先級,並以自訂 PointInfo 模板實例驗證。
ModelMetadata.DataTypeName 來源於 DataTypeAttribute,在模板匹配過程中被視為模板名稱。以下兩種寫法等效:
[DataType(DataType.Html)] [UIHint("Html")]
public string Foo { get; set; } vs public string Foo { get; set; }
[DataType(DataType.MultilineText)] [UIHint("MultilineText")]
public string Bar { get; set; } public string Bar { get; set; }
優先級規則:UIHintAttribute > DataTypeAttribute。若同時存在,僅當 UIHint 指定模板不存在時才回退使用 DataTypeName。
[DataType("PointInfo")]
public Point A { get; set; }
// Point 型別支援字串轉換
[TypeConverter(typeof(PointTypeConverter))]
public class Point { public double X, Y; ... }
建立 Views/Shared/DisplayTemplates/PointInfo.cshtml:
@model MvcApp.Models.Point (@Model.X, @Model.Y)
執行 @Html.DisplayForModel() 時,Triangle 的 A/B/C 三個 Point 屬性自動套用 PointInfo 模板輸出 (1,2) 格式,證明 DataTypeName 確實作為模板名稱被使用。
UIHint/DataType)→ 搜尋 Views/{Controller}/DisplayTemplates|EditorTemplates/{TemplateName}.cshtml → Views/Shared/DisplayTemplates|EditorTemplates/{TemplateName}.cshtmlString.cshtml、Int32.cshtml)
3. 找不到自訂模板 → 使用內建預設模板
自訂分部視圖直接執行渲染;預設模板由 MVC 內部直接產生 HTML。