Asp.net-Mvc-2

“合併”模型和 ViewModel 有或沒有 AutoMapper?

  • September 15, 2016

我目前正在使用 ViewModels 將我的視圖與實際的模型結構分開。

例如,我有一個使用者持久性實體和一個包含所有資訊的 MyProfile ViewModel,使用者可以自行更改這些資訊。對於從 User 到 MyProfile 的轉換,我使用的是 Automapper。

現在,在使用者發回他的(更改的)資訊後,我需要保存這些資訊。但是 ViewModel 中的資訊並不完整,當 AutoMapper 從 ViewModel 創建一個 User 持久化實體時,重要的資訊就會失去。

我不想將這些資訊暴露給視圖層,尤其是隱藏的表單元素。

所以我需要一種將 ViewModel 合併到持久性實體中的方法。我可以使用 AutoMapper 執行此操作,還是必須手動執行此操作?

例子:

我的使用者類包含 ID、名字、姓氏、使用者名和密碼。使用者應該只在他的個人資料中編輯他的名字和姓氏。因此,我的 ProfileViewModel 包含 ID、名字和姓氏。從表單回傳資訊後,Automapper 從傳輸的 ProfileViewModel 中創建一個 User 對象,在該對像中僅設置 ID、Firstname 和 Lastname。將此實體提供給我的儲存庫時,我失去了使用者名和密碼資訊。

所以我需要一種將 ViewModel 合併到持久性實體中的方法。我可以使用 AutoMapper 執行此操作,還是必須手動執行此操作?

是的,您可以使用 AutoMapper 做到這一點。例如:

public class Model
{
   public int Id { get; set; }
   public string Name { get; set; }
}

public class ViewModel
{
   public string Name { get; set; }
}

class Program
{
   static void Main()
   {
       // define a map (ideally once per appdomain => usually goes in Application_Start)
       Mapper.CreateMap<ViewModel, Model>();

       // fetch an entity from a db or something
       var model = new Model
       {
           Id = 5,
           Name = "foo"
       };

       // we get that from the view. It contains only a subset of the
       // entity properties
       var viewModel = new ViewModel
       {
           Name = "bar"
       };

       // Now we merge the view model properties into the model
       Mapper.Map(viewModel, model);

       // at this stage the model.Id stays unchanged because
       // there's no Id property in the view model
       Console.WriteLine(model.Id);

       // and the name has been overwritten
       Console.WriteLine(model.Name);
   }
}

印刷:

5
bar

並將其轉換為典型的 ASP.NET MVC 模式:

[HttpPost]
public ActionResult Update(MyViewModel viewModel)
{
   if (!ModelState.IsValid)
   {
       // validation failed => redisplay view 
       return View(viewModel);
   }

   // fetch the domain entity that we want to udpate
   DomainModel model = _repository.Get(viewModel.Id);

   // now merge the properties
   Mapper.Map(viewModel, model);

   // update the domain model
   _repository.Update(mdoel);

   return RedirectToAction("Success");
}

引用自:https://stackoverflow.com/questions/10248456