Sailing Judo
Sailing Judo

Reputation: 11243

When to use a ViewModel rather than a Model?

I have a business model called Customer which has many required properties (via DataAnnotations) and other validation rules.

I have a View which is meant to allow editing of the customer's address fields.

The problem I have is that I want a strongly-typed view but I can't get away with using the Customer type here. Since the view will only be editing address data it won't return any of the other required data the Customer object would need in order to validate.

This suggests that I should use a ViewModel. However, there are many business rules that apply to the address related properties on Customer that I would have to duplicate on the new ViewModel (address lengths, zipcodes, state formatting, etc). They need duplicated because the client-side validation (I'm using xVal) requires that information in order to function.

I feel I've reached a catch-22 scenario. DRY tells me that I should not duplicate my business rules on a ViewModel that my Model already has, but on the other hand I can't use the Model because it will never validate.

What is the best practice in this situation?

The chosen path

The solution I ultimately chose was the ViewModel path. In order to get the validation I needed to work there was simply no other practical way.

However, was was unable to eliminate some rough spots using the ViewModel brought up. I refactored some of my models to use interfaces containing the properties I knew would re-used in the ViewModels. Since the ViewModels could now use the same interfaces as the models it allowed me to do things like this:

 public ActionResult Edit(AddressViewModel address)
 {
      if(!ModelState.IsValid)
          return View();

      var customer = Customer.Load(address.CustomerId);
      UpdateModel<IAddress>(customer);

      // more stuff ....
 }

This saves me the step of using an automapper.

The answer I selected below (by Wyatt Barnett) I felt was good for most cases and I use it on other projects I have, especially useful with Linq-to-Sql.

Upvotes: 2

Views: 859

Answers (2)

Wyatt Barnett
Wyatt Barnett

Reputation: 15673

I ran into the same issue with complex model classes not playing well with simpler views and model binding. I also happened to be using xVal. The trick I fell upon was to use Validation Buddies to cover the DRY angle for basic validation then use AutoMapper to push things back into the full-blown model classes. I can then run a second round of server-side validation to cover the more complex bits that require access to the database and such.

Upvotes: 1

Scott Whitlock
Scott Whitlock

Reputation: 13839

From a technical standpoing, your view should only talk to your ViewModel, not the model. So your viewmodel should delegate all the validation to the model. The ViewModel should be adding interaction layer stuff.

Of course this all falls apart in Silverlight, where you typically need some kind of quick validation done at the client side, so all of a sudden you're copying all your validation rules up to the ViewModel anyway. I haven't figured a way around that yet.

Upvotes: 0

Related Questions