2012-02-20 64 views
20

在我的控制器填充一個ViewModel我有一個ProductInfo類從我域模型,我需要它的一些信息來填充我的視圖模型ProductStatsVM如何在ASP.NET MVC3

你如何填充視圖模型?我聽到三種可能的方式:

  1. 直接從控制器(不好,我要保持我的控制器苗條)
  2. 通過使用視圖模型構造並通過域模型填充視圖模型作爲參數。 (我必須爲每個要使用的域模型類創建一個構造函數)
  3. 通過使用Fill()方法。 (我在網上看到它,不知道它是如何工作的我猜這樣ViewModel應該知道服務層並創建耦合)。

我知道有一些像AutoMapper這樣的工具,我打算使用它,但是在我想了解如何在不使用任何其他工具的情況下從Controller中填充View Model的邏輯之前。

+0

看起來像你在那裏回答自己的問題。 – dice 2012-02-20 16:34:52

+1

很高興你問這個問題,我很驚訝沒有人有+1這個問題,就像他們今天做的那樣。我一直玩弄各種建議和建議的做法,但Darins的答案是正確的,我的街道,很好的問題,很好的答案。 – LenPopLilly 2012-03-03 16:07:19

回答

27

這個想法是,您的控制器操作查詢某個存儲庫以獲取域模型。然後它會將這個領域模型的映射層負責將其轉換爲一個視圖模型,最後它通過視圖模型到視圖:

public ActionResult Index(int id) 
{ 
    ProductInfo product = repository.GetProductInfo(id); 
    ProductViewModel viewModel = Mapper.Map<ProductInfo, ProductViewModel>(product); 
    return View(viewModel); 
} 

,你甚至可以使你的控制器苗條通過引入自定義動作濾波器將自動攔截模型在OnActionExecuted事件並調用到映射層與相應的視圖模型來替代它,以便你的控制器操作現在變爲:

[AutoMapTo(typeof(ProductViewModel))] 
public ActionResult Index(int id) 
{ 
    ProductInfo product = repository.GetProductInfo(id); 
    return View(product); 
} 

當然現在視圖是強類型到ProductViewModel:

@model ProductViewModel 
... 

由您來執行Mapper.Map<TSource, TDest>方法。如果你不想自己實現它,你可以下載AutoMapper已經有這種方法給你。

映射層是MVC應用程序的一部分。它必須意識到來自服務層的域模型和MVC應用程序中定義的視圖模型,以便能夠執行映射。

請勿在視圖模型中使用構造函數(默認無參數的構造函數)。如果視圖模型在POST操作中沒有無參數構造函數,那麼默認模型聯編程序將會窒息,您將不得不實現定製模型聯編程序。

+0

像往常一樣驚人的清晰和完整。非常感謝! – CiccioMiami 2012-02-20 21:20:21

+0

真的很酷的答案:) – 2012-02-21 11:17:25

+0

順便說一句,你在哪裏配置映射(即Mapper.CreateMap ()...)? – Abe 2012-06-14 23:25:15

1

由於需要viewmodels來填充UI,因此通過控制器填充它們應該是個好主意。你仍然可以通過使用Automapper保持苗條。