Choose the best Client/Server Validation Framework for MVC - asp.net-mvc

Im trying to choose the best server/client validation framework to use with my MVC application. I would like to know what is the best validation framework to use with MVC to do server/client validation.
My options are:
Castle validator
Microsoft Data Annotations
nHibernate Validator

With the upcoming MVC 2, it looks like MS is leaning towards the System.ComponentModel.DataAnnotations library. It's pretty nice - does a lot of code generation for you.

I've been using xVal with great success.
The best thing is you can fully automate validation:
put DataAnnotations (or special rules) to your business layer POCO classes (if you have them) or entity classes' metadata buddy classes if you use entities up to controller layer
write an ActionFilter that will automatically validate parameters to your controller actions - it's best if all your POCOs (or entities) implement a certain interface that defines Validate() method, filter calls this method and fills ModelState.Errors when validation fails.
Add if (ModelState.IsValid) { ... } in your controller action that needs to work differently when model isn't valid
Put <%= Html.ValidationMessage(...) %> in your views that will display validation errors
Add xVal's client validation to your views if desired
This way you've set up automatic object validation. All your controller actions will do is check Model validity.
Asp.net MVC 2 will have something very similar to xVal already built in the framework so it's up to you which version are you using.

Related

Should I use custom model binder to bind view model to entity?

Just some idea to make more use of custom model binder. I am currently still using IMapper interface to do so, though wondering whether part of the purpose of custom binder is to mapping view model or input model to business entity? I can see there might be some limitations if i use MVC custom binder. What is the advantage to use the custom binder in MVC? Will my app gain better performance?
Short answer would be No, you should not
ModelBinder by itself is part of ASP.NET MVC infrastructure. If you would take a look at ASP.NET MVC pipline (PDF) you would see that it's job is
to convert a posted web form data (a string basically) or query string from URL to an instance of particular class.
ASP.NET MVC framework has a DefaultModelBinder that
is suitable for 99% of cases. Custom model binders could be used in situations where standard data conversion fails e.g. mapping $ 1,234.56 from a textbox to a decimal value of 1234.56
Moreover ModelBinder implements IModelBinder interface with a single BindModel() method. This method expects parameters that would be hard to 'hand-craft' to make any use of them and are totally not relevant to your scenario.
What you are realy looking for is
- either custom object mapping between viewmodels and business objects where you manually assign one object property values to another
- or taking advantage of libs/frameworks such as Automapper or ValueInjecter which take care of object mapping hassle away from you
- or a mix of both

Data Annotations and MVC 4

I did MVC 2 two years ago. I am now using MVC 4 and would like to confirm a few things.
1) In MVC 4, we do not need to create a ModelMetadata class to annotate with data annotations for data validation. We may simply annotate the model classes themselves.
In other words, if we are using the EDM generator to generate a model and corresponding classes for us, then we may create a new set of partial classes with the same names and use data annotation attributes on those partial classes themselves.
We do not need to create a new type of model metadata class and decorate that class with data annotation/attributes, like here: http://www.asp.net/mvc/tutorials/older-versions/models-%28data%29/validation-with-the-data-annotation-validators-cs
2) For data annotations to work, we need a reference only to System.ComponentModel.DataAnnotations and not to Microsoft.Web.Mvc.DataAnnotations.
3) We do not need to instantiate the default model binder in the Application_Start event in the Global.asax file.
Could you please confirm if my understanding is correct?
As I remember, there's no difference between MVC 2 and MVC 4 when it comes to this. You didn't have to use MetadataType in MVC 2, you could have used partial classes for generated models.
I'm not able to find any MSDN doc on Microsoft.Web.Mvc.DataAnnotations, but for data annotations to work with MVC you'd need System.ComponentModel.DataAnnotations and System.Web.Mvc (it contains some additional attributes like HiddenInputAttribute).
No, you don't, it's instantiated by framework.
Actually, for question 1, you need to use Metadata classes to annotate the properties of of model-first EF classes in the same way as previously with MVC2. When you use code-first EF classes, you can annotate them directly - the annotations will be used for generating the database as well as for scaffolding the Views.

Where do i place my viewmodel validation?

we are building an ASP.Net MVC application, and we ask ourselve the question where we shoud put the validation logic for incoming data.
We already have the simple validation in place: these are attributes on the viewmodel, like [required], [numeric] , [email] etc. (this is open for discussion too, btw)
But now we have some more input validation: we want to validate if the id's received from dropdownlists are genuine id's.
For example: when we receive 91 as a countryid, i have to make sure 91 is a valid countryid and not a value 'hacked into' the form by a user. Because if it is not a valid countryid, my datalayer generates an error.
Should i place this in the controllers action method, because that
method knows what is right and what is wrong when the data from the request arrives?
Should i place it in a VacancyValidator (the object is a Vacancy
object) where i put all validation logic for all vacancy related
viewmodels
Should i place it in the ViewModel because it should know how to validate itself
Should i create an attribute which validates the property which i place on the ViewModels property
Should i place it in a Vacancy[thisviewmodelsname]Validator where i put all validation logic for this specific viewmodel
Any ideas appreciated....
We already have the simple validation in place: these are attributes
on the viewmodel, like [required], [numeric] , [email] etc. (this is
open for discussion too, btw)
I would recommend FluentValidation.NET instead of Data Annotations which plays nicely with ASP.NET MVC. It provides a nice syntax for expressing complex validation logic between interdependent properties without writing millions of lines of plumbing infrastructure code (which is what you would have to do if you use Data Annotations and write a custom validator) and also allows you to unit test your validation logic very easily.
Because if it is not a valid countryid, my datalayer generates an error.
There you go - your data layer already handles this validation for you. But if you don't want to leave it to reach the data layer then you could have a validation rule for this property on the view model. If you follow my previous advice about FluentValidation.NET you will already know where to put this rule - in the corresponding validator of your view model.
You put your validation obviously to the view model. This way it is located in one spot (not scattered, hence DRY) and operational on both client and server.
For simple scenarios use Data Annotations.
For more sophisticated scenarios (enterprise scale etc) use Fluent Validation
Hope this helps.
The best way is to combine client and server validation. For client side validation you can use jquery validation plugin. It provides all standart validation patterns(like maxlength, minlength, required etc.).You can specify validation requirements in model attributes(data annotation) or directly in html. Also, it provides possibility for custom remote validation when validation result will be returned from server code.
But you should dublicate client side validation with server side. For example, use spring.net validation . I think it's the best generic and flexible framework.

Moving Model Validation to Service Class - ASP.NET MVC

I want to be able to perform validation from within my Service classes. I have a Controller action that looks something like this:
public ActionResult Edit(Post post)
{
if(!ModelState.IsValid)
return View();
_postDataService.SavePost(post);
return View("Index");
}
I don't like the fact that my _postDataService.SavePost() can save invalid data and I want to move the model validation to my _postDataService.SavePost() method. My question is what is the most elegant way to do this? And if I move my model validation to my Service method, how do I return my model errors back to my controller? Lastly, where would model validation like uniqueness of the email address go since it require's some data access? Of all the similar questions i've looked at, none of them give a straight forward way to do this.
I also considered this solution but this article is old and I have a feeling it's not up-to-date.
I assume you are doing validation by putting attributes on properties in your Post model/entity class. If so, you can validate in your service layer by doing this:
var results = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(post,
new ValidationContext(post, null, null), results, true);
This is essentially what the default modelbinder does when it validates and configures the ModelState object for the controller / action.
The beauty of this approach is that you don't have to return validation errors from the service layer. You will just rely on the default modelbinder to do the above code automatically. If someone ever tries to invoke that action without checking ModelState.IsValid, just have your service method throw an exception to remind them.
Update after comment
Yes, my answer recommends doing the validation twice.
How do I feel about it? I don't mind. We use Entity Framework 4.1 with MVC, and do not use entities in MVC. Instead we use automapper to DTO the entities into a separate viewmodel layer. Our EF entities are also decorated with ValidationAttributes, which EF evaluates automatically during any DbContext.SaveChanges() operation. We apply very similar validation attributes on properties of our viewmodel classes. This might not seem DRY, and there is definitely overlap, but in some cases the validation attributes on the UI side can be different than the validation attributes in the domain model.
We do not do validation in a service layer. Our service layer is simply an application flow coordinator, and takes no responsibility for business rules. However, validation still happens twice in our application. First, by the default model binder, against the viewmodel validation rules. Then if the transaction makes it to EF, validation performed against the entities. So we are actually validating 2 separate layers.
If you think about it though, you really are tackling 2 different concerns here. In the UI, you want MVC to display validation messages to users. ModelState is great for this, since it hooks nicely with MVC validation (model binding / jquery / unobtrusive / client-validation / etc).
Conversely in the domain, you are protecting your data integrity and enforcing business rules. The domain doesn't care about displaying messages to a user. For all it knows, the client may be a machine, WCF service, or something else. The role of the domain is to prevent a transaction from occurring, and (in our case) throws an exception rather than quietly trying to "work with" the client.

Concept of ViewModel/Model Validation in ASP.NET MVC + WCF applicaiton

I have the following architecture of my application:
http://clip2net.com/clip/m50879/1303228845-clip-15kb.png
The Model contains a set of POCO objects which should be validated on the web and the services sides.
Also, I have additional ViewModel layer which is being used only on the web side. The ViewModel layer contains the most of validation logic which is the same as the Model validation logic...
The question is:
What is the best approach to avoid copy-paste of the Model validation logic to the ViewModel validation logic?
Maybe this is of interest:
"How to: Validate Model Data Using DataAnnotations Attributes"
http://msdn.microsoft.com/en-us/library/ee256141(VS.100).aspx

Resources