你如何填充/验证你的ViewModels?

Ada*_*SFT 34 model-view-controller asp.net-mvc viewmodel asp.net-mvc-3

我很好奇人们构建ViewModel的各种方式以及他们选择该方法的原因.

我可以在这里想到几种方法:

-1.注入的存储库 - 控制器加载模型并映射到ViewModel.在这里,ViewModel构造函数可以采用各种集合来为ex设置.在选择列表中,例如:


public CustomerController(ISomeRepository repository)
{
   _repository = repository;
}

public ActionResult Create()
{
  CustomerCreateViewModel model = new CustomerCreateViewModel(_repository.GetShipTypes, 
                                                                _repository.GetStates);
..
..
}

-2.ViewModelBuilder - 在控制器中注入或实例化注入存储库的实例.通过类似的东西调用

>var orderViewModel = orderViewModelBuilder.WithStates().Build(orderId);
Run Code Online (Sandbox Code Playgroud)

要么,

var orderViewModel = orderViewModelBuilder.WithStates().Build(orderId);
Run Code Online (Sandbox Code Playgroud)

-3.直接在控制器中(无需代码 - 杂乱无章)

-4.一些其他服务(注入或不注入)返回控制器随后映射的域模型或ViewModel(执行此操作的任何人返回未明确命名/注释为ViewModel构建器类的视图模型?)


public JobCreateViewModel BuildJobCreateViewModel(int parentId)
{
   JobCreateViewModel model = new JobCreateViewModel();
   model.JobStatus = _unitOfWork.JobRepository.GetJobStatuses();
   model.States=_unitOfWork.StateRepository.GetAll();
   return model;
}
Run Code Online (Sandbox Code Playgroud)

现在回程 - 关于验证您的视图模型 - 您是从基础ViewModel类继承标准验证,还是在所有ViewModel之间复制验证(例如数据注释属性),或者只是依赖于服务器端验证,以便它可以再次验证您的域对象吗?

还有其他人?还有什么更好的?为什么?

编辑 根据下面的链接,我确实找到了Jimmy Bogard关于ViewModels架构的好文章.虽然它没有直接解决上面的问题,但对于来这里查看ViewModel信息的人来说,它是一个很好的参考. http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

Dar*_*rov 14

我将服务注入控制器,而不是存储库,然后使用AutoMapper将其转换为视图模型.在这种情况下,服务层的好处是它可以将来自一个或多个存储库的多个简单操作聚合到暴露域模型的单个操作中.例:

private readonly ICustomerService _service;
public CustomerController(ICustomerService service)
{
    _service = service;
}

[AutoMap(typeof(Customer), typeof(CustomerViewModel))]
public ActionResult Create(int id)
{
    Customer customer = _service.GetCustomer(id);
    return View(customer);
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,AutoMap是我可以编写的自定义操作过滤器,它在控制器操作之后执行,检查返回的对象并使用定义的AutoMapper映射将其映射到指定的目标类型.因此视图将相应的CustomerViewModel作为模型类型.本来相当于:

public ActionResult Create(int id)
{
    Customer customer = _service.GetCustomer(id);
    CustomerViewModel vm = Mapper.Map<Customer, CustomerViewModel>(customer);
    return View(vm);
}
Run Code Online (Sandbox Code Playgroud)

只是它太多的管道和重复的代码可以集中.

我还建议你看看把你的控制器放在 Jimmy Bogard 的饮食视频上.

  • 我喜欢`service`解决方案,但我发现这个例子有点过于简单了.在实际案例中,您不仅需要返回客户对象,还需要返回其他类似产品或类别等内容.在这种情况下你的方法是什么?您是否创建了一个特定的服务方法,该方法返回一个更复杂的模型,准备将其展平为特定视图的ViewModel? (2认同)