I like to use a validation service, which doesn't necessarily care about the origin of the data to be validated. This can work in a few different ways when you get to the part about transmitting validation rules to a client (i.e. web page), but I feel the most important aspect of this is to have a single authority for the actual validation rules.
For example, if you have validation logic on your data core entities, like a collection of ValidationRule objects that are checked via a Validate method - a very typical scenario, then I would promote those same rules to the client (javascript) via a transformation.
In the ASP.NET world (the only one I can speak to) there are a couple of ways to do this. My preferred method involves creating custom validators that tie in to your UI widgets to fields (and all their validation rules) on your entities. The advantage of this is that all your validation logic can be bundled into a single validator. The down side is that your validation messages will become dense, since the validation rules are all tested at once. This can, of course, be mitigated by having your validation logic return only a mention of the first failure, etc.
This answer probably sounds sort of nebulous and unspecific, but the two points that I'd like to make are:
- Validation should occur as close as possible to the points where data is entered and where it's committed.
- The same validation rules should be used wherever validation occurs - if client-side validation passes, then it should never fail validation later on (pre-save business rules, foreign key violation, etc.)