這裏有我的解決方案的一些背景:使用自定義ModelBinder在控制器操作中強類型化TPH模型 - 這是否有臭味?
- ASP.Net MVC應用程序
- 使用LINQ到SQL與表每層次結構的繼承
- 使用DataAnnotationsModelBinder默認
所以我有一個Device
抽象類,然後是一系列派生類(ServerDevice
,DiskDevice
,PSUDevice
等),它們以被禁止的Linq-to-SQL方式繼承它。我有一個控制器可以處理所有這些不同的相關模型類型,並根據類型呈現不同的部分,並使用方便的下拉選擇它們。我(GET)創建方法是這樣的:
// GET: /Devices/Create/3
public ActionResult Create(int? deviceTypeID)
{
return View(DeviceFactory(deviceTypeID);
}
凡DeviceFactory
是一個靜態方法返回基於一個int鑑別的一個派生類的新實例。該POST Create方法看起來是這樣的:
// POST: /Devices/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([ModelBinder(typeof(DeviceModelBinder))]Device device)
{
if (!ModelState.IsValid)
return View(device);
_repository.Add(device);
_repository.Save();
TempData["message"] = string.Format("Device was created successfully.");
return RedirectToAction(Actions.Index);
}
和我的自定義模型粘合劑是這樣的:
public class DeviceModelBinder : DataAnnotationsModelBinder
{
private readonly Dictionary<string, Type> _deviceTypes =
new Dictionary<string, Type>
{
{"1", typeof (ServerDevice)},
{"2", typeof (DiskDevice)}
// And on and on for each derived type
};
protected override object CreateModel(ControllerContext controllerContext,
ModelBindingContext bindingContext, Type modelType)
{
return base.CreateModel(controllerContext, bindingContext,
_deviceTypes[bindingContext.ValueProvider["deviceTypeID"].AttemptedValue]);
}
}
所以試圖鉤住這個一整天,閱讀ActionInvoker,定製ActionFilters,和所有後其他MVC的東西,我想知道如果我已經到達的解決方案是一個很好的。幫助消除我擔心我錯過了一些非常明顯的概念並重新發明了方向盤。 有沒有更好或更簡潔的方法?
謝謝!
如果模型是POCO會怎麼樣?它仍然像聽起來一樣糟糕? – 2009-08-28 12:47:12
考慮單一責任原則很重要。如果您需要向視圖添加字段或重新組織視圖(例如,從表格格式到層次結構),則視圖模型可能需要更改。但是如果你重構你的數據庫,那麼你的實體/領域模型需要改變。由於一個類型應該只有一個改變的原因,因此你的實體/域模型和你的視圖模型應該是不同的類型。所以這是使用類型,它們應該是不同的,而不是它們的祖先類型是什麼。 – 2009-08-28 13:23:50
事情我知道之前 - 視圖模型爲驗證和格式化增加了一個很好的擴展點。無論如何 - 你說服了我。去做一些嚴肅的管道工程。 – 2009-08-28 14:34:12