Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asp.NET MVC - Validate a Model Outside of the Controller

I am building an ASP.NET MVC project and going for the following Architecture:

  • A Core project that has models, validation, dto, logic, etc.
  • A ServiceStack API project that acts as my REST API
  • An ASP.NET MVC Web project that is the UI

So, let's say I want to add a user. I define a NewUserInputModel in the Core project. I give it some data annotations such as [Required]. After doing this, the Web project will perform client side validation based on those annotations.

My question is about server side validation. I want to validate the NewUserInputModel using the same rules that are being used on the client side, and I want to run that validation weather the NewUserInputModel comes in from the API or the Web project.

I realize I could call ModelState.IsValid from a Controller in the Web project - but I want to call that validation from the Core project so that all validation logic lives in Core. This way, no matter how this model gets to the Core logic, I always call the same validation. I don't want to leak a System.Web reference into my Core project.

Is this a reasonable design? I think it is - but if something about it smells, I'd be happy to hear it.

Thanks in advance for any help.

like image 259
MattW Avatar asked Nov 19 '13 12:11

MattW


People also ask

How do you check if a model passed into your action method is valid or not?

This action method handles the POST operation and when the form is submitted, the object of the PersonModel class is sent to this method. The state of the submitted Model is checked using ModelState. IsValid property and if the Model is valid then the value of the Name property is set in a ViewBag object.

Which methods can be used to perform validation in MVC?

The following three type of validations we can do in ASP.NET MVC web applications: HTML validation / JavaScript validation. ASP.NET MVC Model validation. Database validation.

What is remote validation in MVC?

ASP.NET MVC 3 provides a mechanism that can make a remote server call in order to validate a form field without posting the entire form to the server. This is useful when you have a field that cannot be validated on the client and is therefore likely to fail validation when the form is submitted.

What is server side validation in MVC?

Server side validations are required for ensuring that the received data is correct and valid. If the received data is valid then we do the further processing with the data. Server side validations are very important before playing with sensitive information of a user.


2 Answers

I consider your approach to be good. Mapping one set of models to another could bring some bugs.

The code you are looking for is:

using System.ComponentModel.DataAnnotations;

var context = new ValidationContext(model, serviceProvider: null, items: null);
var results = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(model, context, results);
if (!isValid)
    throw new Exception("Model is not valid because " + string.Join(", ", results.Select( s => s.ErrorMessage).ToArray()));

For details see http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationcontext.aspx or http://odetocode.com/blogs/scott/archive/2011/06/29/manual-validation-with-data-annotations.aspx

like image 102
Tomas Kubes Avatar answered Oct 03 '22 01:10

Tomas Kubes


I usually keep my view models in the Web project and do the input validation in the controller using the ModelState property. If this succeeds, I map them to domain models (which live in the Core layer) and send those to my services in the Service (could also be Core) layer. The service layer validates business rules and if it succeeds it calls a repository to perform the desired action and returns the result of the operation to the controller.

Keeping your view models in the Web project also allows you to use MVC validation attributes such as RemoteAttribute.

I'm not saying that your design smells, but I do think it's good to separate presentation logic from your Core layer.

like image 42
Henk Mollema Avatar answered Oct 03 '22 00:10

Henk Mollema