2

I am using ViewModels with asp.net MVC3. One of the thing I am curious about is, suppose I have an entity named Customers and it has Add, Edit, Delete screens. Assume that they all have different properties requirements.

For eg. Add may have address field but the edit screen may not have edit screen, delete may only use customer name more than anything else.

My question is, how do you create ViewModels for this? Do you go with the approach of shared ViewModels between add, edit and delete i.e a single viewmodel class that handles all for you or do you prefer to create viewmodels classes / page?

Advantage with shared viewmodel is it reduces development time and we can reuse classes. But big problem with this is that if you are using tool like Automapper you may expected results for different screens.

Disadvantage with one viewmodel/page is that it increases development time. Which way should I go?

Jaggu
  • 6,298
  • 16
  • 58
  • 96
  • 1
    Doesn't Automapper just ignore those fields that are missing or empty from a particular ViewModel? – Robert Harvey Oct 20 '11 at 04:30
  • What if my viewmodel has those field and they are null? It will then assign nulls to my entities and my database will be flooded with columns with null values. – Jaggu Oct 20 '11 at 04:33
  • @Jaggu: Why would values be null? Aren't they populated by the DB, rather than the view? Which two classes are you mapping together, and which values might be null (in each case)? – Merlyn Morgan-Graham Oct 20 '11 at 04:34
  • What I mean is, in shared viewmodel you may have properties that you don't necessarily require for that view but you may require it on different page and so when do Mapper.Map it will assign nulls for properties that are nulls when you do Mapper.map(viewodelsource,modeldest) when infact we didn't wanted them to be assigned null. – Jaggu Oct 20 '11 at 04:35
  • 1
    @Jaggu: You have to exclude those fields from your View that you don't want updated. See http://stackoverflow.com/questions/1803313/asp-net-mvc-partially-updating-model-from-view/1837749#1837749 Also, Automapper has something called Null Substitution, although [the document page that describes it](https://github.com/AutoMapper/AutoMapper/wiki/Null-substitution) is under construction. – Robert Harvey Oct 20 '11 at 04:37
  • @marilyn monroe: Yes they are populated by the db. But when you hit submit button and post request fires you also map them back from viewmodel to model and then save it to database. – Jaggu Oct 20 '11 at 04:38
  • @Jaggu: View model should only contain the union of all fields visible in the different views, not all fields on the persistence model. On Create, it doesn't matter if some fields are mapped to `null`, since you'll have to set them via code convention anyhow. On Delete, you probably have to query an instance from the DB by ID anyhow, so there is no mapping to be done (why bother mapping for just one known field that will never change?). Update will have the most view-visible fields, so should be fully populated, so null mapping shouldn't be an issue. Can you code up a short counter-example? – Merlyn Morgan-Graham Oct 20 '11 at 04:44
  • I think rather than answering my question you are trying to invalidate my whole question :D. Robert suggested a nice link. – Jaggu Oct 20 '11 at 04:47
  • @Jaggu: Or on delete, you might use an entity key, which still will be just one field, so wouldn't require a mapping... Yes, technically that is exactly what I am trying to do :) But not to invalidate - I am trying to help you think of a different way around the problem. Can you see holes in my logic? I'd love to think this problem through and get a bulletproof solution. Other devs have been grumbling about view models a lot at my work lately :) – Merlyn Morgan-Graham Oct 20 '11 at 04:48
  • 1
    It is difficult for me to explain in words. I will come up with a code sample and post it soon. – Jaggu Oct 20 '11 at 04:51
  • See also http://stackoverflow.com/questions/1274575/how-do-you-ignore-persist-values-in-mvc-when-your-view-model-doesnt-have-as-man/1274959#1274959 – Robert Harvey Oct 20 '11 at 05:04

3 Answers3

1

It depends upon situation. if you have similar requirements for different screens (validation, properties to render etc.) you can use the viewmodel across different views. If there is difference of one or two properties, i would still use the same viewmodel and where these properties are not needed i will put them in hidden inputs so they travel back with the form post not allowing unwanted results. Hidden fields, as all know, can be tweaked and its upon developer to decide if it is safe to use hidden fields. However, if i have different validation requirements for two screens then i definitely have to go with viewmodel/page approach. You can mix both approaches according to requirements as they say "there is no best way of doing things"

Muhammad Adeel Zahid
  • 17,474
  • 14
  • 90
  • 155
1

My approach to view models is to use shared view models until the requirements (the data transported) to the view is different. That means I'm using a shared view model for example for CreateAddress and EditAddress in case all data transported to the view is the same. In case an additional field needs to be displayed in the view for example in the CreateAddress view I'm refactoring my view models and using different view models for CreateAddress and EditAddress.

For example for DeleteAddress I'd use a distinct view model from start because I know that the data displayed in the DeleteAddress view is almost never the same as in Create/EditAddress.

Another approach is to use dynamic view models, since view models should/must not implement business logic and act as DTOs between controller and view this approach has some benefits (No need to create logic free, throw away DTOs).

saintedlama
  • 6,838
  • 1
  • 28
  • 46
1

All fields that exists in a model can be changed. It doesn't matter if they are hidden or not. All the user has to do is to inspect your pages and try to figure out what fields exist in the model.

Then he can add those fields (for instance with Chrome Dev Tools) to make changes to them.

The safest way to get rid of that problem is to just have models that only have the fields that are allowed to be changed.

That said, go ahead and use the same model if all fields in the model should be allowed to be changed by all users. (And simply do not show the fields that should not be modified)

jgauffin
  • 99,844
  • 45
  • 235
  • 372