views:

411

answers:

2

I've read a number of articles now in regard to validation and asp.net mvc and the majority tend to point to validation in the model. The problem I see with all of them is that they don't handle different scenarios, or at least, they don't show how they would be achieved e.g.

When creating or updating a user account the email address must match the email confirmation input. This email confirmation input isn't part of the model it's purely to assist correct user input, this might be called a virtual property. When a user logs in using their email address the validation shouldn't try and match the email against a confirmation input, however, in all the examples I've seen there is no way to differentiate between scenarios where the same data is validated in a different way.

Can anybody point me to any mvc validation articles that handle the above types of problem? Or does anybody have any advice on best practices to handle validation like this?

I had thought about introducing a "validation action" such as create, read, update, delete, and then I could validate the same bit of data depending on the context in which it is being used. Anybody have any thoughts on doing things in this manner?

Thanks in advance for any help

+2  A: 

This is why I'm using Validators separated from Models. So, I have IValidator and different validators. For instantiate validator I use DI Container (StructureMap for example).

It was described (not by me) here: http://stackoverflow.com/questions/905313/issues-with-my-mvc-repository-pattern-and-structuremap/924031#924031

dario-g
+2  A: 

According to my experience

1. Validator should be decoupled from controller into separate Service layer like, for instance, showed in this tutorial: http://www.asp.net/learn/mvc/tutorial-38-cs.aspx

2. Service methods may encapsulate all the kind of validation. For example:

    public bool PlaceBooking(Booking booking)
    {
      //Model validation
      IEnumerable<ErrorInfo> errors = DataAnnotationsValidationRunner.GetErrors(booking);
      if (errors.Any())
          _validationDictionary.AddErrors("error", errors);

      // Business rule: Can't place bookings on Sundays
      if(booking.ArrivalDate.DayOfWeek == DayOfWeek.Sunday)
         _validationDictionary.AddError("ArrivalDate", "Bookings are not permitted on Sundays");

      if (!_validationDictionary.IsValid) return false;

      //Errors comming from Data Access Layer
      try
      {
         return _dao.Save(booking);
      }
      catch (DBExecutionException ex)
      {
         if (ex.ResultCode == ResultCodes.RES_UNIQUEINDEX)
          _validationDictionary.AddError("error", "Booking already exists.");
         else
          _validationDictionary.AddError("error", "Some other DB issue happens.");
       }
      return false;
    }
Andrey Tkach