簡體   English   中英

ASP.NET MVC中的ViewModel和域模型

[英]ViewModels and domain models in ASP.NET MVC

我正在開發ASP.NET MVC應用程序,但遇到了一個非常尷尬的情況。

我有一個頁面,用戶可以在其中根據某些條件搜索某些項目(例如,學生)。 我曾經將一組學生傳遞給我的視圖,但是后來我添加了一些要搜索的設置,因此決定按照以下方式創建ViewModel

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

然后我想到了一種情況,當我必須向每個學生添加一些其他信息時,這些信息沒有存儲在數據庫中,而是在控制器上生成的。 我的第一個想法是一個白痴-我添加了一個額外的數組將其保存在ViewModel中,如下所示:

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之類的“幫助器”模型是一個好主意嗎? 我可能不會在SearchViewModel內的任何地方使用StudentViewModel。 鑒於SearchViewModel本身就是一種“幫助”模型,因此創建另一個僅在SearchViewModel內部使用的模型似乎有些奇怪。 是這樣嗎?

  2. 據我了解,ViewModel絕不應該包含域模型。 我應該將學生財產分為較小的財產嗎? 例如,像這樣:

     public class StudentViewModel { public string Name { get; set; } public int GroupId { get; set; } public int someData { get; set; } } 
  3. 一般而言,據我所知,ViewModel應該由基元及其集合(以及第一個問題中的其他ViewModel)組成。 這是正確的嗎?

我不假裝這個不可侵犯的事實。 但我認為:

  1. 通常,視圖模型僅針對一個視圖創建。
  2. 通常在視圖中使用域/數據模型(如果它使開發過程更容易/更快/更清晰)。 在您的情況下,將不會在ViewModel中使用Student類。
  3. ViewModel應該包含構建視圖所需的所有數據(原始而非原始)。 但是,如果您可以通過在控制器中進行一些工作來使視圖模型更輕松,更清晰,那么應該做到這一點。
  1. 創建諸如StudentViewModel之類的“幫助器”模型是一個好主意嗎?

我相信是。 您的視圖“包含”“學生視圖”列表。 視圖模型僅用於以最佳方式構造的數據為您的視圖提供服務,以使視圖中的必要邏輯盡可能少。

  1. 據我了解,ViewModel絕不應該包含域模型。

我建議不要在視圖中使用您的實體,尤其是在處理表單或其他數據輸入方式時。 在這種情況下,創建一個僅包含您希望用戶提交的屬性的特殊“表單模型”通常很有趣。 這也使您可以為此特定形式編寫驗證邏輯。 可以將其視為為您的表單提供服務的模型,類似於視圖模型為您的視圖提供服務的方式。 使用AutoMapper填寫這些表單模型可以使您的生活更輕松。

但是,在某些情況下,我認為在視圖中使用實體是可以接受的:使用EF和延遲加載時,可以在顯示數據時使用實體以從延遲加載機制中獲利。 僅顯示的數據將從數據庫中加載。 但是,由於幾乎總是事先知道您需要哪些數據,因此通常會有更好的數據加載策略。 在開發中發生大量更改時(在無需更改大量代碼的情況下快速且易於實現的加載和顯示其他數據)在開發過程中,惰性加載非常方便,但這通常是性能檢查期間要解決的第一件事。

  1. 我應該將學生財產分為較小的財產嗎? 一般而言,據我所知,ViewModel應該僅由基元及其集合(以及第一個問題中的其他ViewModel)組成。 這是正確的嗎?

我不同意。 您設計了域來表示您的業務對象,為什么還要在視圖模型中再次丟棄它呢? 始終考慮將來可能需要使用其他屬性擴展域模型的可能性,以及您今天可以采取的措施以減少此類更改的成本。 如果要將域層與表示層分開,請引入一個包含相同對象的DTO層。 在這些對象上,您可以應用數據注釋和僅適用於表示層的其他內容。 可以使用AutoMapper快速完成從域對象填充DTO。 但是,請注意不要在這些DTO上/與這些DTO一起編寫業務邏輯。

這是我的2美分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM