Where do you put user input validation in a web form application?
View: JavaScript client side
Controller: Server side language (C#...)
Model: Database (stored procedures or dependencies)
I think there is validation required by each level:
Did the user input a sane value
are dates actual dates, are numbers actualy numbers ...
Do all of the checks in 1. again plus checks for malicious attacks(IE XSS or SQL injection)
The checks done in 1. are mainly to avoid a server round trip when the user makes a mistake.
Since they are done on the client side in javascript, you can't trust that they were run. Validating these values again will stop some malicious attacks.
Are dependencies met (ie. did the user add a comment to a valid question)
A good interface makes these very hard to violate. If something is caught here, something went very wrong.
[inspired by this response]
I check in all tiers, but I'd like to note a validation trick that I use.
I validate in the database layer, proper constraints on your model will provide automatic data integrity validation.
This is an art that seems to be lost on most web programmers.
Validation in the model, optionally automated routines in the UI that take their hints from the model and improve the user experience.
By automated routines I mean that there shouldn't be any per-model validation code in the user interface. If you have a library of validation methods, such as RoR's (which has methods like validates_presence_of :username) the controller or view should be able to read these and apply equivalent javascript (or whatever is convenient) methods.
That means you will have to duplicate the complete validation library in the ui, or at least provide a mapping if you use a preexisting one. But once that's done you won't have to write any validation logic outside the model.
Validation can be done at all layers.
Validating the input from a web form (all strings, casting to proper types, etc) is different from validating the input from a webservice, or XML file, etc. Each has its own special cases. You can create a Validator helper class of course, thus externalising the Validation and allowing it to be shared by views.
Then you have the DAO layer validation - is there enough data in the model to persist (to meet not null constraints, etc) and so on. You can even have check constraints in the database (is status in ('N', 'A', 'S', 'D') etc).
This is interesting. For the longest time I performed all validation in the model, right above what I would consider DAL (data access layer). My models are typically pattern'ed after table data gateway with a DAL providing the abstraction and low level API.
In side the TDG I would implement the business logic and validations, such as:
Is username empty
Is username > 30 characters
If record doesn't exist, return error
As my application grew in complexity I began to realize that much of the validation could be done on the client side, using JavaScript. So I refactored most of the validation logic into JS and cleanuped up my models.
Then I realized that server side validation (not filtering/escaping -- which I consider different) should probalby be done in the server as well and only client side as icing on the cake.
So back the validation logic went, when I realized again, that there was probably a distinct difference between INPUT validation/assertion and business rules/logic.
Basically if it can be done in the client side of the application (using JS) I consider this to be INPUT validation...if it MUST be done by the model (does this record already exist, etc?) then I would consider that business logic. Whats confusing is they both protecte the integrity of the data model.
If you dont' validate the length of a username then whats to stop people from creating a single character username?
I still have not entirely decided where to put that logic next, I think it really depends on what you favour more, thin controllers, heavy models, or visa-versa...
Controllers in my case tend to be far more application centric, whereas models if crafted carefully I can often reuse in "other" projects not just internally, so I prefer keeping models light weight and controllers on the heavier side.
What forces drive you in either direction are really personal opinion, requirements, experiences, etc...
Interesting subject :)
Validation must be done in the controller - it's the only place which assures safety and response.
Validation should be done in the view - it's the point of contact and will provide the best UE and save your server extra work.
Validation will be done on the model - but only for a certain core level of checks. Databases should always reflect appropriate constraints, but it's inefficient to let this stand for real validation, nor is it always possible for a database to determine valid input with simple constraints.
All validation should happen at least one time, and this should be in the middle tier, whether it be in your value objects (in the DDD sense, not to be confused with DTO's), or through the business object of the entity itself. Client side validation can occur to enhance user experience. I tend to not do client side validation, because I can just expose all of the things that are wrong on the form at once, but that's just my personal preference The database validation can occur to insure data integrity in case you screwed up the logic in the middle tier or back ended something.
I only do it in the View and Controller, the database enforces some of that by your data types and whatnot, but I'd rather it not get that far without me catching an error.
You pretty much answered your own question though, the important thing to know is that you can never trust the view, although that's the easiest route to give feedback to the user, so you need to sanitize on at least one more level.
Hmmmm, not sure. I would have said the Controller until I read this article re: skinny Controllers, fat Models
http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models-are-Misunderstood-and-Unappreciated.html
Since most of validations depends on business rules, I do the validation on the business layer as third party tool classes. There are other types of validations, such as user input, whereas it needs to be made in the controller, but you can encapsulate those validation rules in third party classes too. Really, it depends on what to validate.
The client side validations are the minor ones, just made to build a lightweight input validation, but the server side validation is required always. You never can trust in the user input ;)
.NET have nice controls to build validations, but the business layer always needs a better approach to validate the data and those controls are not enough to that task.
Simple input validation in the view. Full validation in the model. Reason? If you change your view technology, and the validation is in the view/controller, you have to rewrite your validation for the new view. This can introduce bugs. Put it in the model, and this is reused by all views...
But, as I said, simple validation in the view for speed and ease.
Related
It is common sense to keep business logic out of controllers. It is also common sense that database access logic should be on a repository, using a repository pattern, as described here: Repository Pattern
However, the repository pattern specifies only very simple low level database operations: Insert, Delete, Update, Select. People advise to keep validation logic out of it too. That is not a problem, since most of the validation can be put inside the model object itself. The problem comes when we need to make some kind of cross-validation, that is, a validation that needs to look on more than one instance of the same model object (for example, ensuring that a name is unique accross all instances of same object) or, even worse, when the validation logic needs to check two or more objects of different types. In this case, we have a real big hole: the business logic cannot be in controller, cannot be in the repository, cannot be in the object model itself (since the logic is not bound only to the object's properties). Where should this logic be? What is the best design pattern for this kind of requirement?
You can create a service layer as described here:
http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validating-with-a-service-layer-cs
The problem here is that your design requires the UI to do validation based on business concerns.
The way to accomplish this is to abstract the validation into the business layer. Your business layer may have methods like ValidateUserIsUnique() and then your ui calls into this layer and receives a result, which is then used for validation.
In particular, for client-side validation MVC provides the RemoteValidationAttribute, but this will only do client-side validation. You will also need to do a server-side validation that calls the same (or a similar) function on the server.
In a typical MVC application we have validation that occurs in many different places. It might be client-side, in the controller, and then again at the data level. If you have a business layer, then there is additional validation there as well.
How do we unify all these so that we're not violating DRY, and causing support nightmares when validations change? A sub-question is how to enable dynamic validation based on the model across all layers.
For example: We may have a ViewModel that has data annotation attributes. In MVC2/3 this unifies client-side and controller validation, but does not help with the data model (unless you are using your data model as your view model, which isn't a good practice).
This means you have to add the same validations to the data model and business layers, duplicating it. What's more, the data model might have subtly different validation requirements than the view model (for instance, an entire data record might comprise several view models of a multi-step wizard. And only a complete record can be saved).
Some people add complex validation to the data model when using an ORM like EF or L2S with partial classes, which i'm not sure is the right path either. It works for apps that are primarily data oriented (data entry type apps), but would not work for apps that have more non-data business logic.
What I'd like is some way to either generate validation for all layers, or a way to hook into a single validation system. Does anything like that exist?
"Fluent Validation" provides better re-usability.
Please visit.
http://fluentvalidation.codeplex.com/
Re-usable documents for Fluent Validation.
http://fluentvalidation.codeplex.com/wikipage?title=CreatingAValidator&referringTitle=Documentation&ANCHOR#ReusingValidators
http://fluentvalidation.codeplex.com/wikipage?title=CreatingAValidator&referringTitle=Documentation&ANCHOR#Collections
Below one may be full fill your needs.
http://tnvalidate.codeplex.com/
I guess I really don't understand your answer since rarely is your data model, business model, and view model all the same. If they are, just use the data model and put the validation on it. The validations across all your layers are specific to the layer.
Example: Your ui should not contain business layer logic in case you ever change the ui layer, or create a new one.
We say that model validation at controllers layer is the correct place to validate all data we gonna operate with. In this case, if we change UI to another (remembering that our layers must be pretty decoupled) the new data validation principles are going to execute - in this case all our inner rules can be violated.
You may say that data models is the separate layer and that layer, but not UI, is the only place for validation. But in this case i found it more effective to validate data in the service or business objects layer, don't i?
In fact we have a number of objects corresponding to our domain object: db table record, linq2sql class, domain object class, viewmodel class. Should it be only one place to validate data model? Why should it be in (or close to) UI but not in the other layer? In my opinion, the validation must occur in the service layer - with all other busness logic. If i need to inform user about error as fast as possible, i'll use client validation in addition to main one. Thoughts? Thank you.
Data validation is the responsibility of the model. The best place to put validation rules in my opinion is as constraints in the database. Having constraints ensures that no incorrect data will ever be stored in the database, no matter how it is access. Unfortunately only basic constraints are suitable to express in the database.
The next place to put validation, when using linq-to-sql for data access, I is the extension methods on the entity classes. Then all code will have to pass through the validation.
To improve user experience, basic validation can be repeated in the UI, but that is just for user experience and to catch the most common mistakes early. On the web, using JavaScript validation is preferable. On rich clients the same code as the one called by the extension methods can sometimes be reused.
Always remember that any service exposed to a client, could be called by a malicious client that lacks the validation that the real client does. Never trust the client to do any kind of validation or security checks correctly.
1.It is validated at UI level because to reduce the one extra hit to server. (EnableClientSideValidation check). And its for basic validations only(like invalid input etc)
2.Many business validations are written in Business layer where they intact irrespective to the UI(WPF or MVC)
3.Usually we write UI validation in controller and specific to MVC.
4.You should keep the validation part as per the prefrences. like sometime we validate entity for unique constraint in such case I would prefer to write my validation attribute over the Entity itself.So at the time of insertion to the database it will be validated.
Also you can try to introduce another layer(new library) here for simplicity and decoupling approach,
This new layer will do, some validation which are not specific to UI and not specific to business logic. We will call it as App Services Layer which also actually helps you to interact with WCF like scenarios. So now your controller and WCF will interact with same layer and with same validation.
Data Validation should happen at the domain level. But UI validation errors should be caught without having to ask someone else downstream.
Unless I'm missing something (which is very possible), it seems to me that custom validation has always violated DRY. In all the examples I've seen, even with the brand new Unobtrusive Client Validation introduced w/ MVC 3, we have to create .NET code for our server-side validation, and jQuery (or JavaScript code) for client-side validation.
I understand that there's no such thing as a .NET-to-jQuery translator that would facilitate DRY server/client validation, and I guess that would be the only way to have true DRY validation that works both server and client side.
But I would be perfectly content with having custom validation always performed on the server. The data needed to pass into custom validation (in my case) is usually limited to one or two fields, and the server-side logic is usually pretty quick, even if it has to hit the database.
Is there no OOTB mechanism for wiring up custom validation using attributes, then having your client side validation use Ajax to execute the validation server-side and respond to the client? Or, has someone come up with such a solution?
Or is it a matter of, in the end, the tradeoffs of repeating the custom validation is better than the issues introduced w/ always executing custom validation server side?
Thanks in advance.
AFAIK, there is nothing OOTB (Out Of The Box).
As for the tradeoffs - though violating DRY, you gain several things:
Immediate feedback to the user (improved usability)
No round tripping in case of validation errors (less load on server)
Of course, apart from violating DRY and opening yourself to those issue, you also end up with a larger payload to the client (extra javascript).
No one can tell you whether these tradeoffs are worth it - you need to decide what is right for your application, users and client.
OOTB: http://msdn.microsoft.com/en-us/library/system.web.mvc.remoteattribute(v=vs.98).aspx
You aren't really validating DRY here. The concept of DRY is a bit more nuanced than simple duplication of code. There are acceptable tradeoffs, especially when coupling concerns are taken into account.
When people ask this question, which is quite often if you search around, I usually refer them to the DDD concept of bounded concepts. Using [Remote] and forcing DRY when it comes to validation tends to bunch up tons of concerns in one place and merging the responsibilities of several layers. Business Logic vs. Persistence and Data Integrity Logic ( non nulls ).
#Darin Dmitrov says it pretty well in a lot of his answers he's made to this exact question. Validating that a required field is filled in is much different from making sure Sally has enough credit to make a purchase and should be treated much differently.
Client validation is best used for basic concerns and not be overloaded with more heavy operations. The impact on usability from client validation is really minimal. There is nothing "unusable" about posting a form and waiting for a refresh. It is more fluent but not anything that will make or break the success of your application.
I don't really share your concerns about violating the DRY principle in this case, but it looks like a couple other people have already discussed that.
However, your idea sounds a lot like the new remote validation feature that was added with MVC 3:
How To: Implement Remote Validation in MVC3
On the other hand, nothing is stopping you from having all of the built-in simple checks performed on the client side, and doing all of the heavy custom validation only when posting back to the server.
I am developing my first DDD application and trying to follow some basic rules I've studied in these last few months.
I've implemented the repository pattern with Nhibernate.
I thought I could have "moved" my entities from the controller to the view, but soon I've realized it's almost impossible.
Most people seem to prefer to define a viewmodel specific for each view.
I don't particularly fancy the idea to redefine the fields I've already create for my entities but it seems that this is the only way.
Now I am facing the situation where I want to attach some validation rules.
I thought I could have attached the validation rules (with DataAnnotations) to the entities but it can't work if I am using a viewmodel.
Here are the questions:
Shouldn't the validation be part of the domain model?
Isn't it time consuming to create the model and then spend time to remap the same fields (properties) on the viewmodel?
Isn't this an anemic model, if it doesn't have, at least, validation rules?
I am starting to wonder if DDD is really suitable for small/medium size application.
I appreciate any help/suggestion.
This has been asked hundreds of times here and I have answered it hundreds of times (so this makes you the hundredth and first person to ask this :-)): put user validation logic on your view models (things like required fields, datetime formats, ...) and put business validation logic on your entities (things like the username has already been taken, the user can no longer purchase products on your site because he has reached the maximum quota, ...).
Shouldn't the validation be part of
the domain model?
I think it should be on both the domain model and the viewmodels. The validation on the viewmodels will check for valid input as to type --datetime, decimal,int, etc whereas the validation on the domain model should check for rules specific to the application. In this way even if you decide to use another UI the business validation will still be in place, while the UI will need to take care of the input validation.
Isn't it time consuming to create the
model and then spend time to remap the
same fields (properties) on the
viewmodel?
There are tools that can help you with that, for example, automapper on codeplex. In my opinion this results in cleaner separation between BLL and UI.
Whereas this approach is in overall more time consuming, it is also more scalable. If your application will need to grow in the future than this is a reasonable way to design the architecture.