从视图模型到域模型的最佳映射位置在哪里?

时间:2011-04-10 09:31:24

标签: c# asp.net-mvc asp.net-mvc-2 asp.net-mvc-3 automapper

从视图模型到域模型进行映射的最佳位置在哪里?通过映射,我的意思是从我的EditGrantApplicationViewModelGrantApplication对象。

假设我有以下操作方法(部分代码):

[HttpPost]
public ActionResult Create(EditGrantApplicationViewModel editGrantApplicationViewModel)
{
   if (!ModelState.IsValid)
   {
      return View("Create", editGrantApplicationViewModel);
   }

   return View("Index");
}

我是否需要将editGrantApplicationViewModel传递给服务层方法并在方法中进行映射?

4 个答案:

答案 0 :(得分:24)

你应该将任何映射逻辑放在服务层内,因为它只是属于那里。映射逻辑应该进入控制器内部而不是其他地方。

为什么你会问?很简单,通过将映射逻辑放在服务层中,它需要知道服务层永远不应该知道的ViewModel - 它还会降低将映射逻辑放在那里的应用程序的灵活性,因为你不能重用服务层而不需要很多黑客。

相反,你应该做类似的事情:

// Web layer (Controller)
public ActionResult Add(AddPersonViewModel viewModel)
{
    service.AddPerson(viewModel.FirstName, viewModel.LastName)
    // some other stuff...
}

// Service layer
public void AddPerson(string firstName, string lastName)
{
    var person = new Person { FirstName = firstName, LastName = lastName };
    // some other stuff...
}

通过如上所述,您可以使服务层更加灵活,因为它没有绑定到特定的类,并且它不知道您的视图模型是否存在。

<强>更新

要将从服务层返回的实体映射到ViewModel,您可能需要查看AutomapperValue Injecter

答案 1 :(得分:4)

直接在控制器中使用AutoMapper或类似框架。

Here is an introduction

答案 2 :(得分:1)

WebUI 图层中执行此操作但不执行控制器而是在其中调用自定义映射器/构建器接口/类

示例http://prodinner.codeplex.com

答案 3 :(得分:0)

我个人永远不会将视图模型传递给服务层。如果沿着这条路线走下去,您的服务最终会直接了解视图上显示的内容。这会导致viewmodel中的更改导致服务层发生更改。

例如: 假设你决定在视图模型中添加一个SelectList,以便进行授权编辑。

public class EditGrantApplicationViewModel
{
   //...
   public SelectList ReasonForEdit {get;set;}
   //...
}

这可能是一个非常有效的要求,但是问自己确实有一个SelectList传递到服务层有意义吗?选择列表更多是UI域,并不对服务层有任何意义。服务层只关心不是选择列表的原因。

我会使用您的视图模型,消化所需的信息,然后将该单元传递到您的服务层。

[HttpPost]
public ActionResult Create(EditGrantApplicationViewModel editGrantApplicationViewModel)
{
   if (!ModelState.IsValid)
   {
      return View("Create", editGrantApplicationViewModel);
   }

   GrantApplication grantApplication = new GrantApplication();
   grantApplication. // other fields.
   grantApplication.Reason = editGrantApplicationViewModel.ReasonForEdit.SelectedValue;
   grantApplication. // other fields.
   _someService.EditApplication(grantApplication);

   return View("Index");
}

如果你还没看过,请查看AutoMapper,因为它有助于在视图模型,dto和其他类之间进行操作。