To validate or not, that is the question

Fact: Users provide wrong data as input.

So we have to check this data before processing it. Btw, not only users can enter wrong data, even data provided by other systems can be wrong and should be validated. Suppose our application has the n-tier architecture as proposed by Microsoft (Application Architecture for .NET: Designing Applications and Services), using custom entity business classes and a webservice layer to provide services to a client. There are several places where you can do validation, but which one to choose?

User interface layer: validation by the client application
The first place where validation can be done, is at the client side, as close to the user as you can get. This validation is pretty easy to implement. You can choose several approaches: for example: check the input each time a TextBox (or other control) loses focus. Or the validation is done before pressing the Ok/Save button, closing the form, ...
In my opinion the second approach is better for several reasons. First of all, by using the first approach the input is only validated when the control loses focus, so you can't be sure of the input, without checking all of the controls again. When using the second approach, be sure to provide one message containing all of the controls that have data that is not correct, instead of displaying a messagebox for each control.

Building validation in the user interface layer seems to way to go. But in the new world of Service Oriented Applications (SOA), there can be multiple client applications using your services. So it's obvious each client application would have to implement validation, which is not so good (always trying to avoid code repetition!). You can argue about the code repetition thing, but since we are living in the SOA world, it's possible we don't write the client application, or our services are accessed directly by other companies. So only client side validation is not enough.

Services interfaces: validation by the webservices and business components
The next place to think about is the Services Interfaces. Since every possible client application uses one ore more of the services interfaces, implementing validation at this level seems to be a good idea. The validation logic is centralized in one place and cannot be surpassed so all data provided by any client application will be validated.

But what could be a problem is passing information about the validation back to the client. Using this approach, data can only be validated by sending it to the server and waiting for a response. So even if the client application only wants to check if the data is entered correctly, a roundtrip to the server is needed.

Next question: how to do the validation? Again, there is no answer that would suit for every situation. You could validate every property in the property set member. This is an easy solution that prevents wrong data to be stored in an object. The drawback of this approach is that you validate one property a time. So suppose your users has entered 2 values for 2 properties, they get validated after each other. This would result in a scenario like this: the users enters it's data and presses the submit button, a message is shown that valueA is wrong, the user corrects it's data and submits again, another message is shown: valueB is wrong. I guess your users would not be happy. Another solution is to build a Validate function. This function would be called after all properties are set, and would do the validation checks. This gives you the advantage that this function can create an error message that informs the user of all properties that are wrong.

Conclusion?
I think there has to be some minimal trivial validation at the client side, so no round trips are needed for example to check if the date is in the correct format. The main part of the validation should be behdind the webservices (Services Interfaces layer). When performance, is one of your main issues, you should use as much client side validation as possible, due to the roundtrips. But as always, performance is not the only issue, so there should be a balance between client side and server side validation. Clients should at least contain some basic validation rules, if your performance constraints allow you, you could consider moving some validation to the server side. But be aware that even when you use very extensive client side validation, server side validation is needed to! Any thoughts would be appriciated!

13 Comments

  • From a performance standpoint, your conclusion misses the mark IMHO. Client-side validation is simply not minimal nor trivial. Sure, business logic tiers can do the most sophisticated validation possible and each tier should be responsible for complete error and validation checks. Sure, point by point everything you say before your conclusion is dead on. But to conclude with the phrase "...some minimal trivial validation at the client side..." is to completely miss the consideration every good developer can never forget: performance.



    A much better way to conclude this excellent post is "... as much validation as the client side can handle...".

  • Dave



    You are completely right! I maybe did not speak about performance. But I do think not all validation can be or should be on the client. I'll make some adjustments to my conclusion.



    Thanks for your reaction!

  • Oh ... you can make it even more flexible if the new custom attributes (like the NonNullAttribute) contain the logic to check the current values.



    let's say:



    public class ValidationAttribute: Attribute

    {

    public abstract ValidationError Validate(object currentvalue, string fieldname);

    }



    public class NonNullAttribute: Attribute

    {

    public override ValidationError Validate(object currentvalue, string fieldname)

    {

    if (currentValue == null)

    {

    return new ValidationError(fieldname + " should not exactly be null.");

    }



    return null;

    }

    }



    The generic Validate(IValidatable obj)-method would then in fact first iterate over all existing fields and properties, then iterate over each custom attribute of the given field/property, checks if the attribute derives from ValidationAttribute, and calls Validate() on each attribute, passing the current value and the field name into it.



    -Ingo

  • I would turn this upside-down. Given the current platform, by default full validation should be implemented both client-side AND service-side. Of course deviations form this scenario do apply, but each one should be a consious descision.

    Unless we can build a Palladium style trusted distributed computing environment, there can be no exceptions to full validation on the service-side. You can not trust your clients integrity.

    Client side there can be lots of reasons to skip full validation, as various trade-offs apply, but the principle should remain: "full validation unless ...".

  • I am speaking off the top of my head here and this was awhile back...



    I vaguely remember some issue I was dealing with then the browser didn't support JScript for whatever reason and thus client-side validators weren't rendered out. I assumed, incorrectly, that the validation would automatically be pushed to the server. If I recall correctly, the server-side validation is only done with an explicit call.



    So, as long as my memory isn't playing tricks on me, that's one more reason why client-side validation shouldn't have too much weight put on it.



    I think you summed it up nicely - "as much validation as possible on the client-side". It's best for perceived performance to the user and scalability by distributing the (arguably minimal) cost of validation to the client. But, you still shouldn't trust that necessarily.



    Remember, it's also possible for me to post a malicious HTTP request to the page w/o using your form at all. Your client-side validation doesn't help much there!

  • For End-2-End .Net apps I tend to put validation code (not strictly business rules) in a DLL and I use that DLL both on the client and on the server.

    On the server I also check all the business rules.



    For other client technologies I tend to implement some validation, it depends on the technology and on the time that I have.

  • Jan, for the record I totally agreed with everything you posted up to the conclusion. I just thought a few adjectives in that conclusion changed the entire meaning of it. Thanks for understanding what I was saying!



    As for the need for server-side validation, I agree with all thoughts presented here. Tim... yes, malicious HTTP requests must be blocked on the server end. Jan... client-side validatation most certainly doesn't lessen the need for server-side too.



    Truth is, every single piece of n-tier development should have all validation and error-checking possible. The objective at each tier may be quite different, but the reasoning behind it isn't. Client-side should always be trying to minimize traffic over the wire. Business-side should always be concerned with logic integrity. Database-side should always be concerned with security. Obviously there's more concerns too... data types, invalid keys, transaction rollbacks, even keeping state of what IS valid.

  • Dave sums it up nicely... so, who are you and do you have a weblog? :)



    (I'd like to subscribe)

  • Nope. I believe I'm becoming well-known around these parts since I do NOT have a weblog yet comment! :P



    I almost started one once but realized I lacked the discipline to post regularly, plus the focus to speak consistantly. Um, I lurk loudly instead!

  • This is an interesting topic. (Jan,I actually came to your blog to ask you a few offline questions about hippo.net which i will submit to you seperately ).



    But back to validation. I am currently in the process of creating a Web services framework where I am consulting (a large cable company in the southeast). We are going over security, exception handling, configuration and last but not least validators.



    Ingo, i was actually approaching the solution in a very similar manner to what you described; however, I was looking hard at creating a base business entity class (for all of my business objects ) that is derived from ContextBoundObject.



    The advantage of using ContextBoundObject is that I can create attributes (much like you describe, but they implement IContextAttribute). I can then decorate my properties and methods with these attributes.



    The key thing about ContextBoundObject is that it enables me to intercept the calls to the assignment of a property or method parameter and evualuate the assignment based on my custom attributes. I can then throw an error if they fail validation.



    What are your thoughts on this everyone? Has anyone done much with this?



    Mathew Nolton

  • Jan,

    I was going through the installation of hippo.net and I noticed a couple of things:

    1) Your readme talks about a config file for your server but the zip file does not have one.

    2) When I start up the client I get the error Requested Service not found (its probably a configuration issue?). I traced it to the line of code in main.vb

    If Me.GetRemoteControl.Notifications.Length > 0 Then



    Any thoughts.

    email me directly at mnolton@cybral.com

    Mathew Nolton

  • Lucy! Please call me,Lucy! Please call me

  • Lucy! Please call me,Lucy! Please call me

Comments have been disabled for this content.