简体   繁体   English

如何在ASP.NET MVC3中填充ViewModel

[英]How to populate a ViewModel in ASP.NET MVC3

In my Controller I have a ProductInfo class from my Domain Model and I need some of its information to populate my View Model ProductStatsVM . 在我的Controller中,我有一个来自我的域模型ProductInfo类,我需要它的一些信息来填充我的View Model ProductStatsVM

How do you populate the View Model? 如何填充视图模型? I heard three possible ways: 我听说过三种可能的方法:

  1. Populate the View Model directly from the Controller (not good, I want to keep my Controller slim) 直接从控制器填充视图模型(不好,我想让控制器保持苗条)
  2. By using a View Model constructor and pass the domain model as parameter. 通过使用View Model构造函数并将域模型作为参数传递。 (I have to create a constructor for each domain model class I want to use) (我必须为我想要使用的每个域模型类创建一个构造函数)
  3. By using a Fill() method . 通过使用Fill()方法 (I saw it on the web, no idea how it works I guess this way the ViewModel should be aware of the Service Layer and creates coupling). (我在网上看到它,不知道它是如何工作的我猜这种方式ViewModel应该知道服务层并创建耦合)。

I know there are tools like AutoMapper, which I am going to use indeed, but before I want to understand the logic on how to fill a View Model from the Controller without using any additional tool. 我知道有些像AutoMapper这样的工具,我确实会使用它,但之前我想了解如何在不使用任何其他工具的情况下从Controller中填充视图模型的逻辑。

The idea is that your controller action queries some repository to fetch a domain model. 我们的想法是您的控制器操作查询某个存储库以获取域模型。 Then it passes this domain model to a mapping layer which is responsible to convert it to a view model and finally it passes the view model to the view: 然后它将此域模型传递给映射层,该层负责将其转换为视图模型,最后将视图模型传递给视图:

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

and you could even make your controller slimmer by introducing a custom action filter that will automatically intercept the Model in the OnActionExecuted event and call into the mapping layer to substitute it with the corresponding view model so that your controller action now becomes: 你甚至可以通过引入一个自定义动作过滤器使你的控制器更加苗条,该过滤器将自动拦截OnActionExecuted事件中的Model并调用映射层以用相应的视图模型替换它,这样你的控制器动作现在变为:

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

and of course now the view is strongly typed to ProductViewModel: 当然,现在视图强烈输入到ProductViewModel:

@model ProductViewModel
...

Up to you to implement the Mapper.Map<TSource, TDest> method. 由您来实现Mapper.Map<TSource, TDest>方法。 And if you don't want to implement it yourself you could download AutoMapper which already has this method for you. 如果你不想自己实现它,你可以下载已经有这种方法的AutoMapper

The mapping layer is something that is part of the MVC application. 映射层是MVC应用程序的一部分。 It must be aware of both the domain models coming from your service layer and the view models defined in your MVC application in order to be able to perform the mapping. 它必须知道来自服务层的域模型和MVC应用程序中定义的视图模型,以便能够执行映射。

Don't use constructors (other than the default parameterless one) in your view models. 不要在视图模型中使用构造函数(默认的无参数构造函数除外)。 The default model binder will choke if the view model doesn't have a parameterless constructor in your POST actions and you will have to implement custom model binders. 如果视图模型在POST操作中没有无参数构造函数,则默认模型绑定器将会阻塞,您必须实现自定义模型绑定器。

Since viewmodels are needed to populate UI, it should be good idea to get them populated via controllers. 由于需要viewmodels来填充UI,因此最好通过控制器填充它们。 You still may keep them slim by using Automapper. 您仍然可以使用Automapper使它们保持苗条。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM