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

时间:2022-01-21 04:12:07

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:1,事情似乎进展顺利。如果我正确理解他们的目的,那么视图模型似乎应该

  1. "Strip down" Entity models so that only relevant properties are passed to the presentation layer
  2. “剥离”实体模型,以便只将相关属性传递给表示层

  3. Add additional information needed for presentation such as a list of state abbreviations or contact types when creating, say, an address.
  4. 在创建地址时添加演示文稿所需的其他信息,例如州名缩写列表或联系人类型。

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.

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

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.

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

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?

输入所有这些属性是其中一个感觉错误的事情。我错过了一个更优雅的解决方案吗?

4 个解决方案

#1


7  

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.

AutoMapper是避免编写您发布的代码的必要条件。我还建议你观看优秀的控制器来自AutoMapper的创建者的饮食视频。观看完这段视频后(以及您身边的一点努力),您的控制器操作将减少到一个漂亮的一个班轮。

#2


4  

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

你一定要看看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));

#3


2  

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.

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

#4


0  

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.

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

#1


7  

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.

AutoMapper是避免编写您发布的代码的必要条件。我还建议你观看优秀的控制器来自AutoMapper的创建者的饮食视频。观看完这段视频后(以及您身边的一点努力),您的控制器操作将减少到一个漂亮的一个班轮。

#2


4  

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

你一定要看看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));

#3


2  

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.

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

#4


0  

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.

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