views:

1127

answers:

10

Say you have a web form with some fields that you want to validate to be only some subset of alphanumeric, a minimum or maximum length etc.

You can validate in the client with javascript, you can post the data back to the server and report back to the user, either via ajax or not. You could have the validation rules in the database and push back error messages to the user that way.

Or any combination of all of the above.

If you want a single place to keep validation rules for web application user data that persist to a database, what are some best practices, patterns or general good advice for doing so?

[edit]

I have edited the question title to better reflect my actual question! Some great answers so far btw.

+16  A: 

all of the above:

  1. client-side validation is more convenient for the user
  2. but you can't trust the client so the code-behind should also validate
  3. similarly the database can't trust that you validated so validate there too

EDIT: i see that you've edited the question to ask for a single point of specification for validation rules. This is called a "Data Dictionary" (DD), and is a Good Thing to have and use to generate validation rules in the different layers. Most systems don't, however, so don't feel bad if you never get around to building such a thing ;-)

One possible/simple design for a DD for a modern 3-tier system might just include - along with the usual max-size/min-size/datatype info - a Javascript expression/function field, C# assembly/class/method field(s), and a sql expression field. The javascript could be slotted into the client-side validation, the C# info could be used for a reflection load/call for server-side validation, and the sql expression could be used for database validation.

But while this is all good in theory, I don't know of any real-world systems that actually do this in practice [though it "sounds" like a Good Idea].

If you do, let us know how it goes!

Steven A. Lowe
This is true, but it doesn't address the issue of defining the rules in one central place.
pkaeding
The question didn't specify the need to define rules in one central place. Additionally many rules are best duplicated. E.g. a character field in a database has a max 50 chars size. This a rule but it would be better for user if you didn't leave it until the DB insert to indicate that.
AnthonyWJones
To pkaeding's point, an interesting debate in comments ( http://thedailywtf.com/Comments/The-Mythical-Business-Layer.aspx ). Amidst all the noise I thought the following comment was level-headed: http://thedailywtf.com/Comments/The-Mythical-Business-Layer.aspx?pg=5#184346
micahwittman
A: 

A good data validation solution could make use of XML Schema based datatypes definition, then both client and server would reuse the types as they would both need to executing it. Worth noting, Backbase Ajax Framework implement client-side user input validation based on XML Schema data types (built-in and user-defined ones)

Sergey Ilinsky
+1  A: 

Always validate every input server-side. You don't know that their client supports javascript "properly", or that they aren't spoofing their http requests and bypassing your javascript entirely.

I'd suggest not limiting your checks to one location though - additional checks within the javascript make things more responsive for your users.

Illandril
A: 
  1. Client-side validation for good, responsive user interfaces
  2. Server-side validation because client-side code can be bypassed or modified and so can't be trusted
  3. Database validation if you have multiple apps feeding into one db. It's important here as then a change to validation is automatically propagated to all apps and you don't lose data consistency.
workmad3
A: 

We try to keep get our validation done before it ever hits the database server, especially for our applications which are facing the public internet. If you don't do validation before the data hits the database, you put your database at risk for SQL-injection attacks. We validation through a mixture of javascript and code-behinds.

Erdrick01
+1  A: 

As others have said, you need to validate on the server side for security and data-integrity reasons, and validating on the client-side will improve the user experience, since users will have a chance to fix their mistakes sooner.

It seemed the question was asking more about how do you define the validations so every place that validates is in sync. I would recommend defining your validation rules in one place, such as an XML file, or something, and having a framework that reads that file, and generates javascript functions to validate on the client. It can then use the same rules to validate on the server.

This way, if you ever need to change a rule, you have one place to go.

pkaeding
+2  A: 

To keep validation rules in one place I use only server-side validation. To make it more user-friendly I just make an asynchronous post request to the server, and server returns error informations in JSON format, like:

{ "fieldName1" : "error description", 
"fieldName2" : "another error description" };

Form is being submitted if the server returned an empty object, otherwise I can use information from the server to display errors. It works much like these sign-up forms that check if your login is taken before you even submit the form, with two key differences: request is being sent onsubmit, and sends all field values (except input type="file").

If JavaScript validation didn't work for any reason, regular server-side validation scenario (page reload with error informations) takes place, using the same server-side script.

This solution isn't as responsive as pure client-side validation (needs time to send/receive data between client and server), but is quite simple, and you don't need to "translate" validation rules to JavaScript.

pawel
This seems like a good compromise, thanks.
Bedwyr Humphreys
+3  A: 

To answer the actual question:

First of all it isn't allways the case that the databse restriction matches client side restrictions. So it would probably be a bad idea to limit yourself to only validate based on database constraints.

But then again, you do want the databse constraints to be reflected in your datamodel. So a first approximation would probably be to defins some small set of perdicates that is mappeble to both check constraints, system language and javascript.

Either that or you just take care to kepp the three representations in the same place so you remember to keep them in sync when changeing something.

But suppose you do want another set of restrictions used in a particular context where the domain model isn't restrictive enough, or maybe it's data that isn't in the model at all. It would probably be a good idea if you could use the same framwork used to defin model restriction to define other kinds of restrictions.

Maybe the way to go is to define a small managable DSL for perdicates describing the restriction. Then you produce "compilers" that parses this DSL and provides the representation you need.

The "DSL" doesn't have to be that fancy, simple string and int validation isn't that much of a problem. RegEx validation could be a problem if your database doesn't support it though. You can probably design this DSL as just a set of classes or what your system language provides that can be combined into expressions with simple boolean algebra.

John Nilsson
A: 

In the past, I've used XSLT for validation. We'd create an XML doc of the values and run it against XSLT. The XSLT was built of XPath "rules." The resulting XML doc was composed of a list of broken rules and the fields that broke them.

We were able to:

  1. store the rules in a relational DB
  2. generate the XSLT from the DB
  3. use the XSLT on the client
  4. use the XSLT on the server
  5. use the raw rules in the DB
harley.333
+1  A: 

As noted by others you have to do validation at the Database, Client, and Server tiers. You were asking for a single place to hold validation so all of these are in sync.

One approach used by several web development frameworks (including CakePHP ) Is to organize your code into Model, View, Controller objects.

You would put all your data code including validation in the model layer (comments for database table structure or stored procedures if needed).

Next, In this Model define a regular expression for each field for your validation (along with generic max-size, min-size, required fields).

Finally, use this regular expression in to validate in javascript (view) and in on the server form processing code (Controller).

If the regex isn't sufficient - ie you have to check the database to see if a username is available, you can define a validation method on the model use it directly in your form processing code and then call it from javascript using ajax and a little validation page.

I'll put in a plug for starting with a good framework so you don't have to wire all this up yourself.

Bryan Waters