ASP.NET MVC:如何处理具有许多属性的视图模型?

发布于 2024-09-26 00:25:38 字数 850 浏览 0 评论 0原文

因此,我的视图与视图模型的比例几乎为 1:1,而且一切似乎进展顺利。如果我正确理解它们的目的,那么视图模型似乎应该

  1. “剥离”实体模型,以便仅将相关属性传递到表示层
  2. 添加表示所需的附加信息,例如创建时的状态缩写或联系人类型列表,例如,一个地址。

为了遵守这些原则,我的报告控制器有点碰壁了。为客户生成的各种报告需要访问大约 30 个左右的不同属性。因此,我的视图模型最终看起来与我的实体模型非常相似。

当然,最简单的解决方案是将实体模型传递到视图,以便我可以访问所有属性,但是我还需要能够为空白或“不完整”的客户生成报告。当尝试访问实体模型上的导航属性时,这会导致出现空引用异常问题。

因此,我可以对视图中的几乎每个字段使用空检查,这看起来不太吸引人...或者我可以实现一个视图模型来避免空引用异常。问题是我最终会得到一个看起来像这样的视图模型:

var customer = customersRepository.GetCustomer(id);
var viewModel = new CustomersViewModel()
{
    FirstName = customer.FirstName,
    LastName = customer.LastName,
    Address = customer.MailingAddress.Address,
    City = customer.MailingAddress.City,
    // and on and on for about 30 different properties
};
return View(viewModel);

将所有这些属性键入出来是感觉错误的事情之一。我是否缺少一个更优雅的解决方案来解决这个问题?

So I have an almost 1:1 ratio of views to view models and things seem to be going well. If I understand their purpose correctly it seems that view models should

  1. "Strip down" Entity models so that only relevant properties are passed to the presentation layer
  2. Add additional information needed for presentation such as a list of state abbreviations or contact types when creating, say, an address.

In trying to keep with those principles I've sort of hit a bit of a wall with my Reports controller. Various reports that are generated for a customer require access to about 30 or so different properties. As such, my view model ends up looking very similar to my Entity model.

Of course the easiest solution is to just pass the Entity model to the view so that I'll have access to all properties, however I also need to be able to generate reports for blank or "incomplete" customers. This causes problems will null reference exceptions when trying to access navigation properties on my Entity models.

So I can either use a null check on just about every field within the view, which doesn't seem too appealing... OR I could implement a view model to avoid the null reference exceptions. The problem is that I'd end up with a view model that looked like this:

var customer = customersRepository.GetCustomer(id);
var viewModel = new CustomersViewModel()
{
    FirstName = customer.FirstName,
    LastName = customer.LastName,
    Address = customer.MailingAddress.Address,
    City = customer.MailingAddress.City,
    // and on and on for about 30 different properties
};
return View(viewModel);

Typing all those properties out is one of those things that just feels wrong. Am I missing a more elegant solution to this problem?

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

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

发布评论

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

评论(4

夏の忆 2024-10-03 00:25:38

问题是我最终会得到一个看起来像这样的视图模型

AutoMapper 是必须避免编写的正是您发布的代码。我还建议您观看精彩的让您的控制器节食 来自 AutoMapper 创建者的视频。观看此视频(以及您这边的一些努力)后,您的控制器操作将简化为漂亮的一行。

The problem is that I'd end up with a view model that looked like this

AutoMapper is a must to avoid writing exactly the code you posted. I would also recommend you watching the excellent put your controllers on a diet video from the creator of AutoMapper. After watching this video (and a bit of an effort from your side) your controller action will be reduced to a pretty one liner.

横笛休吹塞上声 2024-10-03 00:25:38

您绝对应该研究一下 AutoMapper ( http://automapper.codeplex.com/ )。

AutoMapper.Mapper.CreateMap(typeof(CustomersModel), typeof(CustomersViewModel));

AutoMapper.Mapper.CreateMap<CoolObject, CoolObjectViewModel>()
    .ForMember(d => d.Property1, f => f.MapFrom(s => s.Property1))
    .ForMember(d => d.Property2, f => f.MapFrom(s => s.Property2))
    .ForMember(d => d.Property3, f => f.MapFrom(s => s.Property3));

You should definitely look into AutoMapper ( http://automapper.codeplex.com/ ).

AutoMapper.Mapper.CreateMap(typeof(CustomersModel), typeof(CustomersViewModel));

AutoMapper.Mapper.CreateMap<CoolObject, CoolObjectViewModel>()
    .ForMember(d => d.Property1, f => f.MapFrom(s => s.Property1))
    .ForMember(d => d.Property2, f => f.MapFrom(s => s.Property2))
    .ForMember(d => d.Property3, f => f.MapFrom(s => s.Property3));
彼岸花似海 2024-10-03 00:25:38

输入所有这些属性是感觉错误的事情之一

无论您想要达到哪个级别,最终都必须键入所有属性。

所以,我认为这种方法同样可以。

Typing all those properties out is one of those things that just feels wrong

To which ever level you would want to take, eventually you'll have to type all.

So, I see this approach as equally ok.

神也荒唐 2024-10-03 00:25:38

我真的不明白你在这里想要实现的目标.. 编写更多代码没有任何问题.. 只要代码具体且组织良好,代码的大小并不重要。您应该担心的是如何减少数据库交互,仅从数据库中检索所需的属性。

正如您的代码所示,您检索整个客户对象,然后最终显示一些属性,为什么不只检索您需要的属性。

另外,如果您使用邮寄地址的属性,为什么不将整个 mailingaddres 对象作为属性传递,为什么要拆分为其他属性。

I really dont get what you are trying to achieve here.. there is nothing wrong in writing more code.. it doesnt matter what the size of you code is so long as it is concrete and well organised. what you should be worrying is how do you reduce database interactions, retrieve only required properties from the db.

as your code shows you retrieve the entire customer object and then end up displaying some properties why dont you retrieve only the properties that you need.

also if you are using the properties of Mailing address why dont you pass the entire mailingaddres object as a property why are you splitting up into other properties.

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