Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewModel ends up being a copy of Model - where is the benefit?

Another question I asked on here has opened a can of worms for me. Currently I have development my MVC application, with models representing my data and used scaffolding to generate my ViewControllers from those models. Where the models didn't have the required information in, I was using partial views to show the relevant information. After some reading I now understand ViewModel's to be the better way of doing things. So my understand is that for each view I will have a specific ViewModel that returns the data for that view.

I have two models, one representing an item and the other, the item options of which there may be multiple.

public class Item
{
    public int ItemId { get; set; }
    public bool Active { get; set; }
    public string ItemCode { get; set; }
    public string Name { get; set; }
    public List<ItemOption> ItemOptions { get; set; }
    //...
}

public class ItemOption
{
    public int ItemOptionId { get; set; }
    public string Name { get; set; }
    public string Barcode { get; set; }
    //...
}

Therefore I assume my ItemDetailViewModel will just contain the information I show to the user in the view:

public class ItemDetailViewModel
{
    public bool Active { get; set; }
    public string ItemCode { get; set; }
    public string Name { get; set; }
    public List<ItemOption> ItemOptions { get; set; }
}

Should I be making my ItemOptions list on the ItemDetailViewModel there own list? For example should it be:

public List<ItemOptionsViewModel> ItemOptions { get; set; }

I think I am missing the benefit of the ViewModel. I've read that it's so we can have all the data in one class relevant for that view and therefore we can keep the view strongly typed. However I seem to just be copying my Models into my ViewModels, so not really gaining any benefit.

In addition, my research has lead me to thinkking AutoMapper is the best way forward. Am I correct in saying I just put the following in my start up config:

Mapper.CreateMap<Item, ItemDetailViewModel>()
            .ForMember(x => x.Active, o => o.MapFrom(s => s.Active))
            .ForMember(x => x.ItemCode, o => o.MapFrom(s => s.ItemCode))
            .ForMember(x => x.Name, o => o.MapFrom(s => s.Name));
            .ForMember(x => x.ItemOptions, o => o.MapFrom(s => s.ItemOptions));

If I do this, how does it work for the edit views. If I save them back to the ItemDetailViewModel will it update my database in EF?

like image 983
Joseph Avatar asked Mar 21 '23 04:03

Joseph


1 Answers

Use a view model when there's a benefit. If your domain model already has the exact same properties and validation rules and error messages corresponding to this particular view as your view model does then it is obvious that you could reuse your domain model and you don't need to declare a view model. But from my experience that's seldom the case. Or if it is the case then you might start asking yourself why your domain models are so coupled to the views. I mean error messages specific to a view should not be part of a domain model.

So as always you should find the right balance. It's common to have a main view model which aggregates (as properties) one or more domain models.

As a side remark in your AutoMapper configuration you don't need to be mapping each property if it has the same name. That's why the framework is called AutoMapper, because it works by convention. All this long mapping code shown in your question is equivalent to a more simple Mapper.CreateMap<Item, ItemDetailViewModel>();.

like image 88
Darin Dimitrov Avatar answered Apr 06 '23 17:04

Darin Dimitrov