Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where should be the validation in a ASP.Net MVC scenario having Repository, Service Layer and using Model Binder?

Related: What’s the best way to implement field validation using ASP.NET MVC?

Let's suppose a solution with the following projects:

Foo; // the MVC web project
Foo.Models;
Foo.Repositories;
Foo.Services;

Foo.Models is the domain of the application with all the entities, doesn't matter if using EF, NH, POCO or whatever. Here's an example:

public class User
{
    public string Username { get; set; }

    public string Email { get; set; }

    public string Password { get; set; }
}

In Foo.Repositories there is a UserRepository and in Foo.Services there is a UserService.

In the web application let's consider a model binder like following:

public class UserBinder : DefaultModelBinder
{
    //...
}

I see three different options on where to put the validation:

  • In Foo.Models like the following:

    public class User
    {
        public string Username { get; set; }
    
        public string Email { get; set; }
    
        public string Password { get; set; }
    
        public ICollection<KeyValuePair<string, string>> ValidateErrors()
        {
            //Validate if Username, Email and Password has been passed
        }
    }
    
  • In Foo.Services like:

    public class UserService
    {
        public ICollection<KeyValuePair<string, string>> ValidateErrors()
        {
            //Validate if Username, Email and Password has been passed
        }
    }
    
  • In Foo inside the model binder:

    public class UserBinder : DefaultModelBinder
    {
        protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var user = (User)bindingContext.Model;
    
            // validate everything here
    
            base.OnModelUpdated(controllerContext, bindingContext);
        }
    }
    

Another thing to notice is that considering the first 2 options [Model and Service] there is another decision to make: ValidateErrors method can be called directly on the controller or inside the Binder.

I have 2 questions on the scenario:

  1. Should the validation be:

    • In the Model being called from the controller?
    • In the Model being called from the binder?
    • In the Service being called from the controller?
    • In the Service being called from the binder?
    • Directly in the Binder?
    • Any other idea?
  2. All the above scenario discuss about the User creation. But what about User logon? Let's say user uses the username and password to login in the application, so it won't need to validate the e-mail. Where this validation should be?

    • In the Model being called from the controller?
    • In the Service being called from the controller?
    • Any other idea?
like image 533
homemdelata Avatar asked Nov 05 '22 21:11

homemdelata


2 Answers

Check out the ASP.NET MVC Contact Manager Sample Application it has a very good architecture im my opinion

http://www.asp.net/learn/mvc/tutorial-26-cs.aspx'>http://www.asp.net/learn/mvc/tutorial-26-cs.aspx

like image 163
Soni Ali Avatar answered Nov 14 '22 23:11

Soni Ali


I'm a big fan of putting calling the validation from the controllers and having the validation routine return an ActionResult so the controller can know what to do with the result.

like image 37
Peter Mourfield Avatar answered Nov 14 '22 23:11

Peter Mourfield