ASP.NET MVC - Mapping with Automapper
I'm currently trying to figure out when to use ViewModels and when not to. I'm using Automapper for the task and currently have the following code:
// AccountController.cs
[AuthWhereRole(Roles = AuthorizeRole.Developer)]
public ActionResult List()
{
MembershipUserCollection users = _memberShipService.GetAllUsers();
IEnumerable<ListUsersViewModel> viewModel =
Mapper.Map<IEnumerable<MembershipUser>, IEnumerable<ListUsersViewModel>>(users.Cast<MembershipUser>().AsEnumerable());
return View("List", viewModel);
}
// ListUsersViewModel.cs
public class ListUsersViewModel
{
public Guid Id { get; set; }
public virtual string UserName { get; set; }
public string LastLogOn { get; set; }
}
// Bootstrapper.cs
public static void ConfigureAutoMapper()
{
Mapper.CreateMap<MembershipUser, ListUsersViewModel>()
.ForMember(x => x.UserName, o => o.MapFrom(s => s.UserName))
.ForMember(x => x.Id, o => o.MapFrom(s => s.ProviderUserKey))
.ForMember(x => x.LastLogOn, o => o.MapFrom(s => s.LastLoginDate));
}
I'm wondering whether its bad practice to map like this just 开发者_运维问答to exclude some properties from the domain model? - And should I always use View Models, even when not needed?
Thanks in advance.
In short, yes you should always use a ViewModel.
We use AutoMapper on our project and initially we did not provide separate ViewModels for each view. We found that we had some performance issues that cropped up if objects have references to each other (i.e. User has Logins which have Roles which have Users). AutoMapper didn't know when to stop building up these collections.
While this was not a problem on simple pages, such as the one in your example, we decided to create a ViewModel for each View that provided only the properties neede by that ViewModel. This resolved the permissions issues and also makes it very easy to see the information the View requires.
Jimmy Bogard talks about following this method in a blog post: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspx
Here's a great article on AutoMapper and ViewModels
http://weblogs.asp.net/shijuvarghese/archive/2010/02/01/view-model-pattern-and-automapper-in-asp-net-mvc-applications.aspx
Some key points.
Your question should I always use View Models, even when not needed?
The comment on the blog post says
Domain objects are designed for the needs for domain model and it is representing the domain of our applications. On the other hand, View Model objects designed for our needs for views.
And here's how he's describing using the automapper. I think the idea of the AutoMapper is that it will map what it can based on the names of the properties.
[HttpPost]
public ActionResult Create(ContactViewModel contactToCreate) {
if (ModelState.IsValid) {
Contact newContact = new Contact();
AutoMapper.Mapper.Map(contactToCreate, newContact);
contactRepository.CreateContact(contactToCreate.GroupId, newContact);
}
}
In my not-so-extensive experience, the rule of thumb goes as follows:
- For views that display THE Domain Model as is (Like a record before you hit the "edit" button), than you can just use your plain model. Although, that doesn't stop you to create another class that simply extends your Domain Model, so in the future you don't have to touch both the Controller and the View.
- For the rest of the cases: ViewModels. Here are some reasons why
- If you have totals (like number of students in a class), rather than calculating that on the view, the ViewModel should have a method of its own.
- Pagination. Usually when displaying many records, you have either: AllRecords, or some quantities of pagination stacks (20, 50, 100, for ex.). The Domain Model should just serve the Business Logic in general (and prevent you to add that your Telephone Number is "Fish" for example), but the viewmodel is concerned of mantaining a state of the view
So I guess, yeah, kind of always
精彩评论