WHAT'S NEW?
Loading...

MCSD Web Applications: Data validation, Data contracts and Unhandled exceptions

Index


  • Intro
  • Data validation
  • Data contracts
  • Unhandled exceptions
  • References

Intro

Today I'm talking about some interesting topics about how to defend your applications from users. Why do you have to know this? Simply. It's because users never know what they are doing and this is fact. In this post we'll try to validate the information provided by the user so we can get rid of some errors.


Data validation

Data validation is testing values introduced to an application, via a service, file or data entry) against expected values and ranges. Imagine a typical register form in a web and a naughty user setting is name in the DOB field, his DOB inside the name textbox and so... This technique will help you to avoid these users and some errors like these:

  • Prevent overflow
  • Prevent incorrect results
  • Prevent undesirable side-effects
  • Provide guidance to systems of users
  • Prevent security intrusions

But... before starting validating the info introduced by our users (or any other source), first we need to validate our data as developers. At this stage the compiler appears but not validating data, mainly validating object type, better said, validates the envelope but not the content.

Another tool you can use to prevent wrong data is Assert. You can create a test set in your application to prevent bad use or modification of your methods.

As a reaction to wrong data you can raise exceptions in your code. Depending on which one is the error you've detected you can trigger one of the following exceptions (there are plenty of these in the .net framework):
  • System.ArgumentException
  • System.ArgumentOutOfRangeException
  • System.ArgumentNullException
See the following example of exception usage:

public override void SetName(string value)
{
    // validate empty
    if (string.IsNullOrWhiteSpace(value))
        throw new ArgumentNullException("value");

    // validate conflict
    if (value == this.Name)
        throw new ArgumentException("value is duplicate");

    if (value.Length > 10)
        throw new ArgumentException("value is too long");

    this.Name = value;
}

In the previous example you can appreciate how we can validate (if) the content of a particular property and react proving an exception to the caller class.

Data contracts

Again, data validation. The phrase "design by contract" comes from the ancient programming language "Eiffel" and is a unique system that can replace all other approaches to data validation.

Microsoft data contract is an add-on you can install in Visual Studio. The add-on will help you to stablish all the assumptions you want in your code to be validated. The aim of a contract is to document your code as well as external APIs and then, as part of the compiling phase you will get your code checked.

The big difference between using Exceptions or Data contracts is that the first one, only validates data when our app is running, but Data contracts validate our conditions in runtime and statically in design. Code contracts have preconditions (requires) and post-conditions (ensures). 

Please see here below an example of data contracts usage:


In the set method of our awesome dog class we call the static method "requires" from the Contract class where we first pass a condition and the we setup a message when that condition is not covered. In our get method we stablish a contract to avoid returning empty strings by using the "ensures" method.

With data contract we can even configure build errors in order to avoid data validation mistakes. We can also call "Contract.EndContractBlock();" method just after our bunch of if-then-throw statements and this will turn all of those exceptions into contract violations.

Note: As a good practice you shouldn't use contracts for security checking because security exception could ignore that contract violation, but everything else makes complete sense.

Unhandled exceptions

Now is time to handle exceptions, not just throw them, but also, track the flow of our app to provide proper error messages and validations.

What happens with all of those exceptions thrown by your code or the runtime outside of a try block. The runtime handles all exceptions protecting the system, not your app. This causes: instability and termination. It's now when a try/catch/finally statement is really useful, see:

public void UpdateGeoCoordinates(Job job)
{
    var address = job.GetAddress(); // get the address as string

    var gps = _locator.GetGpsCoordinates(address); // get the gps coords

    try
    {
        job.Lat = Double.Parse(gps.Item1, CultureInfo.InvariantCulture);
        job.Lng = Double.Parse(gps.Item2, CultureInfo.InvariantCulture);
    }
    catch (FormatException)
    {
        Logger.Warn("Job [{0}], format error when convert '{1}', '{2}' to a Double.", job.Id, gps.Item1, gps.Item2);
    }
    catch (OverflowException)
    {
        Logger.Warn("Job [{0}], overflow when convert '{1}', '{2}' to a Double.", job.Id, gps.Item1, gps.Item2);
    }
    catch (Exception ex)
    {
        Logger.Warn("Job [{0}], Exception message: {1}", job.Id, ex.Message);
    }
    finally
    {
        ReleaseResources();
        Logger.Warn("Process executed");
    }
}


In the code above, I'm converting some GPS coordinates from string into a double data type. This is a real example from a production project.

I've defined some different catch blocks (FormatException and OverflowException) to show you how you can grab a particular error and react accordingly to that error. As last catch, I've used generic Exception to assure that I'll always got any error from my code.

You can think of "finally" as a kind of optional promise. It's something reliable that you know will always be executed, maybe releasing resources or by providing a message. Keep in mind is an optional block in the try/catch statement so don't have to provide it by default.

What is also important to think about here is assumptions. Consider you opened files in the "try" block, then, one of those files couldn't be opened, which produces run your catch block because the exception. If you planned to close those resources (files) within the finally statement you probably end in another error because of that invalid resource which produced the first exception. So be very careful with your finally blocks in order to introduce more errors.

References

http://www.microsoftvirtualacademy.com/training-courses/developer-training-with-programming-in-c
http://techterms.com/definition/compiler

0 comments:

Post a Comment