MVC 模式中,Model 封裝業務邏輯與資料,View 負責呈現,Controller 協調兩者。實務上,直接將領域模型傳給 View 會導致安全風險 (Over-posting)、顯示邏輯汙染領域模型、介面需求變更波及資料層。引入 View Model (或 Application Model / DTO) 是解決之道。
| 維度 | 領域模型 | 視圖模型 |
|---|---|---|
| 用途 | 表達核心業務規則、不變條件、資料一致性 | 單純服務特定 View 的顯示/輸入需求 |
| 結構 | 豐富物件圖、繼承、導航屬性、驗證邏輯內建 | 扁平化、僅含簡單型別 (string, int, DateTime...)、無行為 |
| 資料範圍 | 完整業務實體 | View 所需欄位子集,可能合併多個領域實體 |
| 格式差異 | 如:DateTime OrderDate | 如:int DaysUntilShip (下拉選單天數)、string FormattedDate |
| 安全性 | 含敏感欄位 (IsAdmin, Salary) | 僅暴露允許編輯/檢視的欄位 |
public Customer DomainModel { get; set; },View 透過 Model.DomainModel.Name 存取,仍暴露完整物件圖。IsAdmin=true)。自動化領域模型 ↔ View Model 映射,慣例大於配置:
Mapper.CreateMap<Customer, CustomerViewModel>();
var viewModel = Mapper.Map<CustomerViewModel>(domainCustomer);
支援扁平化 (Customer.Address.City → CustomerViewModel.City)、自訂解析器、條件映射等進階功能。
[HttpPost]
public ActionResult Edit(CustomerViewModel viewModel)
{
if (!ModelState.IsValid) return View(viewModel);
var customer = _repository.Get(viewModel.Id);
Mapper.Map(viewModel, customer); // 反向映射更新領域模型
_repository.Save(customer);
return RedirectToAction("Index");
}
View Model 是表現層的專用資料契約,隔離領域模型複雜度與安全風險。雖增加映射代碼,但配合 AutoMapper 可大幅降低成本,換取系統長期可維護性與安全性,是專業 ASP.NET MVC 開發的標準做法。