I am building an ASP.NET MVC project and going for the following Architecture:
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.
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.
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.
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.
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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With