在MVC當中時常會用到ViewModel,它的概念很直覺就是字面上的意思,給View用的Model,但請注意它跟MVVM概念中所提到的ViewModel是不一樣的!
在mvc的View中,我們知道一個View Binding一個Model如:@model MVCProject.Models.Product
,那我們再View中如果要用到其他Table的資料呢?我們就可以用ViewModel來達成。
那如果我們不透過ViewModel呢?我們可以使用ViewBag或是ViewData來達到效果,但相對的就沒有強型別的效果了。
因此我們可以大概歸納出,使用ViewModel的時機為,一個畫面需要使用到兩個以上Table的資料時,但既然強調了這個ViewModel為View產生的,在設計此class時,請不要加入任何方法或Service,雖然一樣可以執行,卻會造成專案混亂難以維護,如果一個專案夠龐大,他在原本的Model有Create()方法,在某個ViewModel又有Create()一樣Table的方法,當你邏輯改了,這些就要跟著調整,因此不建議在ViewModel中,對db做任何事情。
預計畫面
在Product的Create畫面中,有個欄位是下拉式選單,要顯示Company Table中的Name
Step1:在Model底下建一個資料夾,「ViewModel」
Step2:建立一個.cs,命名規則為「Controller+ViewModel」
Step3:打ViewModel內容
public class ProductViewModel
{
[Key]
public int Id { get; set; }
[DisplayName("產品名稱")]
[Required(ErrorMessage ="必填欄位")]
public string ProductName { get; set; }
[Required(ErrorMessage = "必填欄位")]
[DisplayName("公司ID")]
public int CompanyId { get; set; }
[Required(ErrorMessage = "必填欄位")]
[DisplayName("價格")]
public decimal Price { get; set; }
[DisplayName("啟用")]
public bool Active { get; set; }
[DisplayName("庫存")]
public int Stock { get; set; }
[DisplayName("下架")]
public bool IdDeleted { get; set; }
[DisplayName("公司名稱")]
public virtual List<CompanyModel.Company> CompanyName { get; set; }
}
Step4:接著在Product的Controller建Create(Get/Post)Action Method
public ActionResult Create2()
{
var Company = new CompanyModel();
var Companylist = Company.Get();
var productViewModel = new ProductViewModel();
productViewModel.CompanyName = Companylist;
return View(productViewModel);
}
首先初始化ViewModel後,把要用到的資料Company丟給ViewModel productViewModel.CompanyName = Companylist;
Step5:接著建立View
請注意「資料內容類別」預設為db,需清空,因為ViewModel並不存在這個Table,會造成錯誤。
Step6:稍微改變一下內容加入Dropdwonlist
@Html.LabelFor(model => model.CompanyId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.CompanyId,new SelectList(Model.CompanyName,"CompanyId","Name"),"----請選擇公司名稱----")
@Html.ValidationMessageFor(model => model.CompanyId, "", new { @class = "text-danger" })
</div>
即可顯示結果畫面
文初所提到的MVVM的ViewModel,套在MVC的架構上,角色有點像原本的Controller,只是多包了Model,透過Bindings和View做溝通,所以在流程上與純存為了View建的ViewModel透過Controller將資料包給View顯示的概念是不一樣的。