views:

1321

answers:

10

Where do you put user input validation in a web form application?

  1. View: Javascript client side
  2. Controller: Server side language (C#...)
  3. Model: Database (stored procedures or dependencies)

I think there is validation required by each level:

  1. Did the user input a sane value
    • are dates actual dates, are numbers actualy numbers ...
  2. 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.
  3. 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]

+5  A: 

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.

FlySwat
Right, but a failed insert isn't as easy to find the *reason* it failed from.
UltimateBrent
Sure it is, SQLErrors bubble back up to the business tier in my designs, and the business tier is then aware of why it failed.
FlySwat
But why bother letting it get that far when you could've easily checked before? You can validate the data just as easily as you parse the error message.
UltimateBrent
Because when you have 10,000 concurrent users, the only place of sanity is the data model, Lots of errors that "would" be caught in the business logic can sneak by when you have lots of concurrent transactions.
FlySwat
There are often very complex constraints to be met in a database. Any good database is optimized to evaluate these dependencies quickly and efficiently. It is often faster to let the database fail than it is to ask the database for the relevant records and do the check in the business layer.
alumb
I guess it depends on what type of validation you're doing. Honoring UNIQUE keys in the database is probably easier on that level, but there's still plenty I'd rather keep at business. Good points though.
UltimateBrent
+3  A: 

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).

JeeBee
The question wasn't where it could be done, but where it should be done. "All layers" seems a little over the top for me. Speed should be a factor in all applications.
alumb
Speed should be a factor. The massive overhead of some minor checks will be far outweighed by HTTP and network overhead however.
JeeBee
A: 

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.

UltimateBrent
+4  A: 

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.

MattW.
Could you flush out what you mean by "automated routines"?
alumb
+2  A: 

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.

Charles Graham
+2  A: 

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:

  1. Is username empty
  2. Is username > 30 characters
  3. 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 :)

+3  A: 

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.

annakata
A: 

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

sunwukung
A: 

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.

daniel
A: 

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.