假设我有一个对象
class MyItem
{
public string Name {get; set;}
public string Description {get; set;}
}
我想创建一个ViewModel
class MyItemViewModel
{
public string Name {get; set;}
public string Description {get; set;}
public string Username {get; set;}
}
我想在 Controller 上获取一个 MyItem 类型的对象并自动填充 ViewModel。使用 MyItem 中包含的值(即,如果它有一个名为 Name 的属性,则自动填写它)。
我试图避免的是 Model.Name = Item.Name
行的列表。 MyItemViewModel 也将具有不同的属性和显示值,因此我不能简单地将 MyItem 嵌入到 View 模型中。
是否有一种干净的编程方式可以在对象之间复制具有相同名称和类型的属性,或者我是否需要手动完成?
最佳答案
你可以使用 AutoMapper为了这个任务。我在所有项目中都使用它在我的域模型和 View 模型之间进行映射。
您只需在 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 方法并用相应的 View 模型替换传递给 View 的模型:
[AutoMap(typeof(MyItem), typeof(MyItemViewModel))]
public ActionResult Index()
{
MyItem item = ... fetch your domain model from a repository
return View(item);
}
这使您的 Controller 操作非常简单。
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");
}
例如,假设您有一个包含用户名、密码和 IsAdmin 等属性的用户域模型,并且您有一个允许用户更改其用户名和密码但绝对不能更改 IsAdmin 属性的表单。因此,您将拥有一个包含绑定(bind)到 View 中 html 表单的用户名和密码属性的 View 模型,使用此技术您将只更新这 2 个属性,而 IsAdmin 属性保持不变。
AutoMapper 也适用于集合。一旦定义了简单类型之间的映射:
Mapper.CreateMap<MyItem, MyItemViewModel>();
在集合之间映射时不需要做任何特殊的事情:
IEnumerable<MyItem> items = ...
IEnumerable<MyItemViewModel> vms = Mapper.Map<IEnumerable<MyItem>, IEnumerable<MyItemViewModel>>(items);
所以不要再等了,在您的 NuGet 控制台中键入以下命令并欣赏节目:
Install-Package AutoMapper
关于c# - 复制不同类型对象的最简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11970567/