您可以使用AutoMapper来完成此任务。我在所有项目中都使用它来映射我的域模型和视图模型。
您只需在您的 : 中定义一个映射Application_Start
:
Mapper.CreateMap<MyItem, MyItemViewModel>();
然后执行映射:
public ActionResult Index()
{
MyItem item = ... fetch your domain model from a repository
MyItemViewModel vm = Mapper.Map<MyItem, MyItemViewModel>(item);
return View(vm);
}
您可以编写一个自定义操作过滤器,它会覆盖 OnActionExecuted 方法并用相应的视图模型替换传递给视图的模型:
[AutoMap(typeof(MyItem), typeof(MyItemViewModel))]
public ActionResult Index()
{
MyItem item = ... fetch your domain model from a repository
return View(item);
}
这使您的控制器操作非常简单。
AutoMapper 有另一种非常有用的方法,当您想要更新某些内容时,可以在您的 POST 操作中使用它:
[HttpPost]
public ActionResult Edit(MyItemViewModel vm)
{
// Get the domain model that we want to update
MyItem item = Repository.GetItem(vm.Id);
// Merge the properties of the domain model from the view model =>
// update only those that were present in the view model
Mapper.Map<MyItemViewModel, MyItem>(vm, item);
// At this stage the item instance contains update properties
// for those that were present in the view model and all other
// stay untouched. Now we could persist the changes
Repository.Update(item);
return RedirectToAction("Success");
}
例如,假设您有一个包含 Username、Password 和 IsAdmin 等属性的 User 域模型,并且您有一个允许用户更改其用户名和密码但绝对不更改 IsAdmin 属性的表单。因此,您将拥有一个包含 Username 和 Password 属性的视图模型,该属性绑定到视图中的 html 表单,并且使用此技术您将只更新这 2 个属性,而不会更改 IsAdmin 属性。
AutoMapper 也适用于集合。一旦定义了简单类型之间的映射:
Mapper.CreateMap<MyItem, MyItemViewModel>();
在集合之间进行映射时,您不需要做任何特别的事情:
IEnumerable<MyItem> items = ...
IEnumerable<MyItemViewModel> vms = Mapper.Map<IEnumerable<MyItem>, IEnumerable<MyItemViewModel>>(items);
所以不要再等了,在你的 NuGet 控制台中输入以下命令并享受表演:
Install-Package AutoMapper