Question

We have some view models where the validation contained in the view model is being replicated in the controller. Further to this we have some logic that I'm not sure if its appropriate for the view model or controller.

  1. Does a viewModel validate both client and server level, if is this automatic or do we need to implement something.
  2. A field such a username where you need a db call to check for availability should this validation be in a view model or httppost of the controller.

Thanks in advance.

Was it helpful?

Solution

If you are using standard ASP.NET MVC model validation providers:

  1. Yes, but only predefined set of rules like Required or Range, they have identical client side and server side implementation, note that client side validation should be enabled (include validation js files, set appSettings parameters).
  2. It depends on real application, but mostly it's business logic that should be a part of controller processing, but in some cases you could try Remote validation attribute.

Also take a look into FluentValidation as a good alternative implementation.

OTHER TIPS

  1. If you're using validation attributes then it will occur at both. Client-side validation is a nice feature but shouldn't be relied upon. Server-side validation is what is critical.
  2. I consider this to be a business rule rather than validation. Validation should just be checking that the input is valid (i.e. is it a string or an integer, is it within the minimum and maximum range?). The validation should be simple and minimalist. Checking to see if a username is valid or already exists is a business rule and should be a separate issue.

Take a look at System.ComponentModel.DataAnnotations for validation that might help you.

Calls to the database should not be at the UI level. Keep your database usage separate from your presentation logic. Don't do it in the view model, and don't do it in the controller (if you can avoid it). It's best to have the controller call something at the domain service layer (business logic layer) that's referencing the data layer.

That might change from case to case, but as a general rule, if you're using default items/scripts from ASP.NET MVC (including jQuery.Validate.Unobtrusive), here follows:

Does a viewModel validate both client and server level, if is this automatic or do we need to implement something.

Yes and no. Depends on your case/project/referenced scripts/rules used. There should be a jquery.validate.unobtrusive.js item on your project along with a jquery.validate.js and, of course, a jquery.js for client-side validation to take place automatically (unobtrusively).

But client-side validation rules are limited and they won't validate everything. On the other hand, you can extend it quite easily. When a validation rule is not supported on client-side and you don't implement that rule, it will get validated only on server-side.

Unobtrusive validation is there to help you with automatic client-side validation, instead of manually checking each field for valid input/selection. It's not perfect, but should work fine on most cases.

A field such a username where you need a db call to check for availability should this validation be in a view model or httppost of the controller.

There's no "universal rule" for that, as some people would argue that db-related method must be on a repository, some would allow it on controllers and since this is related to validation, some would validate it inside the validation rule.

I'm into putting this kind of rules into either the controller or a repository, the one that looks finer for your.

On our projects when we have some extra validity-related checks that need any db call, they call a method on a controller which delegates the call to a repository. This allows us to call the same method from both client and server side, whenever needed (eg: check if already taken username right after typeing it).

Final considerations

Personally, I don't like DataAnnotations. I used to, but not anymore, as it get's really hard to keep on a large-scale project with complex-multi-validations and more.

I'd suggest you go for FluentValidation which has a nice fluent interface and is extensible. It too allows both client-side and server-side validation and allows you to perform complex tasks in a friendly way.

For instance, we've created a custom rule (with it's client-side part) to check for already-registered emails, which calls a controller and receives a json result to parse and validate the field. This way, we simply have a RuleFor(_account => _account.Email).NotAlreadyTaken() and the email get's validated on both client and server-side, and you get that through ModelState.IsValid just as with the DataAnnotations.

But before you ask if this is not possible with DataAnnotations (or someone else comes here to say that it's possible), yes this is possible without FluentValidation. I think it's more of a personal choice really.

The interesting part of FluentValidation is that you can have a separate assembly only with validations and provide all that validations using Ninject or any other IoC.

Anyway, check this tutorial on how to begin with client-side validation with DataAnnotations, or FluentValidation website to start using FluentValidation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top