2014-11-23 64 views
0

我正在開發一個ASP.NET MVC應用程序,並且我遇到了一個非常尷尬的情況。ViewModels和ASP.NET MVC中的域模型

我有一個頁面,用戶可以通過一些標準搜索一些項目(比如學生)。我以前的學生集合傳遞給我的看法,但我已經添加了一些設置進行搜索,所以我已經決定要創建視圖模型如下

public class SearchViewModel 
{ 
    public string SearchString { get; set; } 
    public bool IsCaseSensitive { get; set; } 
    ... 
    //other parameters 
    ... 
    public IEnumerable<Student> Students { get; set; } 
} 

然後我想過的情況時,我必須向每個學生添加一些額外的信息,這些信息並不存儲在數據庫中並在控制器上生成。我的第一個想法是很愚蠢的一個 - 我已經添加了額外的陣列將其保存在視圖模型是這樣的:

public class SearchViewModel 
{ 
    public string SearchString { get; set; } 
    public bool IsCaseSensitive { get; set; } 
    ... 
    //other parameters 
    ... 
    public IEnumerable<Student> Students { get; set; } 
    public IEnumerable<int> someData { get; set; } 
} 

這樣得到的數據,客戶端代碼就一定得在學生的位置數組,然後轉到someData數組中的相應位置。

我不太喜歡這個想法,所以我改變了我的模型,包括搜索參數+一個額外的模型來保存學生對象和他們的數據。

public class SearchViewModel 
{ 
    public string SearchString { get; set; } 
    public bool IsCaseSensitive { get; set; } 
    ... 
    //other parameters 
    ... 
    public IEnumerable<StudentViewModel> StudentModels { get; set; } 
} 

public class StudentViewModel 
{ 
    public Student Student { get; set; } 
    public int someData { get; set; } 
} 
  1. 這是個好主意來創造這樣的 '幫手' 模型作爲StudentViewModel?我可能不會使用StudentViewModel,但在SearchViewModel內部。鑑於SearchViewModel本身就是一種「幫助」模型,創建另一個僅在SearchViewModel中使用的模型似乎有點奇怪。是這樣嗎?

  2. 據我發現,一個ViewModel不應該包含域模型。我應該將學生資產分成較小的資產嗎?舉例來說,像這樣:

    public class StudentViewModel 
    { 
        public string Name { get; set; } 
        public int GroupId { get; set; } 
        public int someData { get; set; } 
    } 
    
  3. 一般來說,因爲我已經明白,一個視圖模型應該包括只有原語及其藏品(和可能,其他的ViewModels作爲第一個問題)。這是對的嗎?

回答

1

我不假裝這個不可侵犯的事實。但在我看來:

  1. 很多時候,視圖模型只爲一個視圖創建。
  2. 通常在視圖中使用域/數據模型(如果它使開發過程更容易/更快/更清晰)。在你的情況下,我不會在ViewModel中使用學生類。
  3. ViewModel應該包含構建視圖(基元而不是基元)所需的所有數據。但是,如果您可以通過在控制器中執行一些工作來使視圖模型更容易,更清晰,那麼就應該完成。
1
  1. 創建像StudentViewModel這樣的'助手'模型是個好主意嗎?

我相信是的。你的觀點'包含''學生觀點'列表。 Viewmodels僅用於以最佳方式構建數據來爲視圖提供視圖,從而使視圖中的必要邏輯儘可能最小化。

  1. 據我發現,ViewModel不應該包含域模型。

我建議不要在視圖中使用您的實體,特別是在處理表單或其他數據輸入方式時。在這種情況下,創建一個特殊的「表單模型」通常很有趣,該表單模型僅包含您希望用戶提交的屬性。這也允許你爲這個特定的表單編寫驗證邏輯。將其視爲服務於您的表單的模型,類似於視圖模型如何服務於您的視圖。使用AutoMapper來填充這些表單模型,使您的生活更輕鬆。但是,在某些情況下,我覺得在視圖中使用實體是可以接受的:當您使用EF和延遲加載時,您可以在顯示數據以從延遲加載機制中獲利時使用實體。只有你顯示的數據會從數據庫中加載。但是,由於幾乎總是事先知道您需要哪些數據,因此通常會有更好的數據加載策略。延遲加載在開發過程中非常方便,因爲在進行大量更改時(加載&顯示更快的數據更容易實現,無需更改大量代碼),但通常是在性能評估過程中首先要解決的問題。

  1. 我應該將學生資產分成較小的資產嗎?一般來說,正如我所理解的,ViewModel應該只包含原語及其集合(可能還包括其他ViewModel,如第一個問題)。這是對的嗎?

我不同意。你設計了你的域來代表你的業務對象,爲什麼你會在視圖模型中再次拋棄它?始終考慮未來可能性,即您的域模型需要額外的屬性進行擴展,以及您今天可以做些什麼來降低此類更改的成本。如果您想要將表示層與表示層分開,請引入一個包含相同對象的DTO層。在這些對象上,您可以應用數據註釋和僅適用於表示層的其他內容。使用AutoMapper可以快速完成從域對象填充DTO。但是,請注意不要在這些DTO上編寫業務邏輯。

這是我的2美分。

+0

謝謝。我唯一不完全理解的是你的第三個答案。參考你的第二個答案,我不應該在我的Views中使用任何領域模型(通常的Student,不是StudentViewModel)。然而,那麼你說我實際上應該使用我的學生課。我是否正確地認爲最好的方法是1)保持領域模型學生不變,2)使用StudentViewModel來滿足視圖的需求,而不是將其劃分爲不同的屬性?另外,我對DTO條款不太滿意。我的ViewModels可以被視爲DTO嗎? – 2014-11-24 18:42:12