如何在 ASP.NET MVC3 中填充 ViewModel

发布于 2025-01-07 12:40:35 字数 489 浏览 3 评论 0原文

在我的控制器中,我的域模型中有一个ProductInfo类,我需要它的一些信息来填充我的视图模型ProductStatsVM< /代码>。

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

  1. 直接从控制器填充视图模型(不好,我想让我的控制器保持苗条)
  2. 通过使用视图模型构造函数并传递域模型作为参数。 (我必须为我想要使用的每个域模型类创建一个构造函数)
  3. 通过​​使用 Fill() 方法。 (我在网上看到它,不知道它是如何工作的,我想这样 ViewModel 应该知道服务层并创建耦合)。

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

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.

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. (I have to create a constructor for each domain model class I want to use)
  3. By using a Fill() method. (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).

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凝望流年 2025-01-14 12:40:35

这个想法是您的控制器操作查询某个存储库以获取域模型。然后,它将这个域模型传递给映射层,映射层负责将其转换为视图模型,最后将视图模型传递给视图:

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 方法。如果您不想自己实现它,您可以下载 AutoMapper,它已经为您提供了此方法。

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

不要在视图模型中使用构造函数(默认的无参数构造函数除外)。如果视图模型在 POST 操作中没有无参数构造函数,则默认模型绑定器将会阻塞,并且您必须实现自定义模型绑定器。

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:

[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:

@model ProductViewModel
...

Up to you to implement the Mapper.Map<TSource, TDest> method. And if you don't want to implement it yourself you could download AutoMapper which already has this method for you.

The mapping layer is something that is part of the MVC application. 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.

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.

倒带 2025-01-14 12:40:35

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

Since viewmodels are needed to populate UI, it should be good idea to get them populated via controllers. You still may keep them slim by using Automapper.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文