如何在ASP.NET MVC3中填充ViewModel

20

在我的控制器中,我有一个来自我的领域模型ProductInfo类,并且我需要一些它的信息来填充我的视图模型ProductStatsVM

如何填充视图模型?我听说有三种可能的方法:

  1. 直接从控制器填充视图模型(不好,我想保持我的控制器简洁)
  2. 使用视图模型构造函数并将领域模型作为参数传递。(我必须为每个要使用的领域模型类创建一个构造函数)
  3. 通过使用Fill()方法。(我在网上看到过,不知道它是如何工作的。我猜这种方式视图模型应该意识到服务层并且会产生耦合)

我知道有像AutoMapper这样的工具,我确实要使用它,但是在此之前,我想了解如何在不使用任何其他工具的情况下从控制器填充视图模型的逻辑。


看起来你已经回答了自己的问题。 - dice
1
很高兴你问了这个问题,我很惊讶没有人像他们在过去那样点赞这个问题。我一直在试验各种建议和提出的做法,但Darin的答案正好符合我的需求,好问题,好回答。 - LenPopLilly
2个回答

27

这个想法是你的控制器动作查询某个仓库来获取一个领域模型。然后它将这个领域模型传递给映射层,负责将其转换为视图模型,最后将视图模型传递给视图:

public ActionResult Index(int id)
{
    ProductInfo product = repository.GetProductInfo(id);
    ProductViewModel viewModel = Mapper.Map<ProductInfo, ProductViewModel>(product);
    return View(viewModel);
}

您甚至可以通过引入自定义操作筛选器来使您的控制器更加精简,该筛选器将自动拦截 OnActionExecuted 事件中的模型,并调用映射层来替换它为相应的视图模型,使您的控制器操作现在变成:

[AutoMapTo(typeof(ProductViewModel))]
public ActionResult Index(int id)
{
    ProductInfo product = repository.GetProductInfo(id);
    return View(product);
}

当然,现在该视图已经强类型化为 ProductViewModel:

@model ProductViewModel
...

你需要自己实现Mapper.Map<TSource, TDest>方法,如果你不想亲自实现,可以下载AutoMapper,它已经为你提供了这个方法。

映射层是 MVC 应用程序的一部分。它必须了解来自服务层的领域模型和 MVC 应用程序中定义的视图模型,才能执行映射操作。

在视图模型中不要使用构造函数(除了默认的无参构造函数)。如果你的视图模型在 POST 操作中没有一个无参构造函数,那么默认的模型绑定器将无法工作,你将不得不实现自定义的模型绑定器。


顺便问一下,你在哪里配置映射(即 Mapper.CreateMap<ProductInfo, ProductViewModel>() ...)? - Abe
1
@Abe,这应该只在AppDomain的生命周期内完成一次,最好是在从Application_Start调用的方法中完成。 - Darin Dimitrov
谢谢!我在OnApplicationStarted()方法(Ninject)中配置了global.asax.cs文件的映射,它起作用了! - Abe

1

由于视图模型需要填充UI,因此通过控制器填充它们应该是一个好主意。您仍然可以使用Automapper使它们保持精简。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接