Jerad Rose
Jerad Rose

Reputation: 15513

In MVC3, should I have separate "edit" models vs. "display" models?

With MVC3, should I design my view models such that there is one that is bound to the view (DisplayModel), and one that is posted back to the controller (EditModel)?

To clarify, I am not asking about data models vs. view models -- I know it's not good to bind my views/controllers to data/domain models.

Nor am I asking about sharing one model across two separate views, one view that is used for displaying the data, and another view that is used for editing the data.

Rather, I am asking about one view that is used for editing data, and the model that is bound to the view vs. the model that is bound to the controller action.

In other words, if this is my view:

@model MyApp.Models.CustomerModel

Should my controller action look like:

public ActionResult Index(CustomerModel model)

Or:

public ActionResult Index(CustomerEditModel model)

At one point, we were doing the latter (separate). But lately, we've started doing the former (shared).

The reason for this change was because:

  1. With MVC3 unobtrusive validation, if I'm using DataAnnotations on my model for validation, this is needed in both models if they are separated (on the display model to map client-side validation, and on the edit model for server-side validation).

  2. As our application matured, we realized that our display and edit models were 95% identical, with the exception of the select lists that were in our view models. We've now moved these to a shared class and are passing these in via the view now.

But I've seen some other discussions that point to having shared models for view/controller to be a bad idea, and that it violates separation of concerns.

Can someone help me understand the tradeoffs for these two approaches?

Upvotes: 20

Views: 3591

Answers (6)

Bret Walker
Bret Walker

Reputation: 1806

I agree with rich.okelly's answer that there's no right approach.

There are a couple of concerns I have with using one model, though.

It's going to be very to always use one model without having unneeded properties when the view needs to display a selectable list of objects. The model will need to have the list of objects as well as a property to accept the POSTed value the user chooses. These unneeded properties add a small amount of code clutter and overhead. (One way around this is to have the model contain only selected ID and have HTML helpers to build the lists.)

Another concern is more related to security. A common scenario is displaying information in a form that should be considered read-only. In the case of a ViewModel and an EditModel, the EditModel will only contain properties that are expected to be POSTed, whereas the ViewModel will contain all of the properties. For example, if a form displays a user's salary, a user will be able to POST a 'salary' and have it bound to the ViewModel's Salary property automatically by MVC. At this point, something has to be done to ensure it doesn't end up in the database. It could be if/else logic, a Bind attribute, Automapper logic or something else, but the point is that it's a step that could be overlooked. When considering the lifespan of an application, I like the explicitness of the EditModel over time.

These concerns don't mean that two models are good and one model is bad, but they should be considered when choosing a design.

Upvotes: 3

Adam Tuliper
Adam Tuliper

Reputation: 30152

No - one view model for both directions. Mixing it up is not only harder to follow, but one could easily inject invalid values into the page that then get automatically bound. I could overwrite your customerid (or create one) for example.

Inherit from a base view model if you must or don't rely on data annotations at all and use the fluent api on your model save.

A great link (somewhat unrelated but the auto map is nice)

edit (sorry someone else previously posted this below I just realized) http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

Also ASP.net MVC - One ViewModel per View or per Action?

You (IMHO) should be generally binding to your method specific VieWModel rather than a shared view model. You could get caught in a trap of missing properties, etc. but it may also work just fine for you.

Use auto mapper to go between both. Jimmy also has a nice AutoMap attribute when returning to the View. Going back the other way I would not use a CustomerModel in general as there may be fields required in there that are not coming from my say, create view. For example a customer id may be a required field and for a "create" action it won't be present. But - if you find in the most of your cases this to actually work for you, then there is no reason at all not to use it.

Upvotes: 1

Hector Correa
Hector Correa

Reputation: 26690

we realized that our display and edit models were 95% identical, with the exception of the select lists that were in our view models. We've now moved these to a shared class and are passing these in via the view now.

Are they 95% identical in data and operations or only in data? Remember that classes encapsulate data and behavior.

If they are 95% similar in properties but have totally different operations you might benefit from splitting them in two classes. Or you might not :)

As others pointed out there is no one-size-fit-all answer and in your case it seems that one class is OK...but if you start noticing that the behavior on each of them is unrelated don't be afraid to rethink you approach.

Upvotes: 1

Billy Coover
Billy Coover

Reputation: 3837

I think you'll find that it's hit or miss no matter what way you go but if you can take the path of easiest maintainability then you should do that. In my experience, having a single model is much easier to maintain, obviously, but it seems that there is always some business decision that is made that forces me to split the models. If you're in that 95% then I think you are in really good shape. Your application, from a maintainability perspective related to your models, will be easy to maintain. When a change comes along, you have one place to make that change, for the most part. The issue I always seem to run into is scaling business changes across multiple models. Copy/paste issues, or simply forgetting about some property somewhere, always seems to hurt me because of the multi-model issue.

Upvotes: 2

Rich O'Kelly
Rich O'Kelly

Reputation: 41757

I've seen perfectly good arguments for and against, it just depends what works best for your application. There's no one size fits all approach that can be applied!

If you haven't read it Jimmy Bogard has written a very good post about how his team does MVC here, which covers this topic.

Upvotes: 7

jrummell
jrummell

Reputation: 43077

If the properties are the same for display and edit view models I see no reason to have separate classes.

Upvotes: 2

Related Questions