Geeks With Blogs
Blog Moved to Blog Moved to
In a previous post, I shared my ArgumentValidator class as well as an overview of Regular Expressions.  I want to revisit this topic because of the fact that I hadn't really optimized it for ASP.NET 2.0.  There are some features now offered in .NET 2.0 that help the process of keeping your messages standard.  Also, I'd like to re-address some of the regular expression things as well.
Let's go ahead and create a new ASP.NET 2.0 Web Site.  From here, we have the basic Default.aspx/cs.  From this page we will add two controls to validate.  They would look something similar to this:
<asp:TextBox ID="txtEmployeeID" runat="server" />
asp:RegularExpressionValidator ID="valEmployeeID" ControlToValidate="txtEmployeeID" runat="server" />
<asp:TextBox ID="txtZipCode" runat="server" />
<asp:RegularExpressionValidator ID="valZipCode" ControlToValidate="txtZipCode" runat="server" />
Now that we have the web page, let's go ahead and initialize the validator controls with some of the more constant data.   I would rather not hard code certain validations in the UI as they can change.  I also do not want to hard code the actual error message displayed should the validations fail.  This is especially important in globalized applications.
private void InitializeControls()
     this.valEmployeeID.Text = ResourceMessageManager.EmployeeIDInvalidMessage;
     this.valEmployeeID.ValidationExpression = ArgumentValidator.EmployeeIDExpression;
     this.valZipCode.Text = ResourceMessageManager.ZipCodeExceptionMessage;
     this.valZipCode.ValidationExpression = ArgumentValidator.ZipCodeExpression;
} // method - InitializeControls
Now what I did here is I set the validator text to constants that I am reading in from my Strings.resx file.  Visual Studio automatically creates a Resources.Strings hard class for you to use.  The reason why I still use ResourceMessageManager is that some of the messages may require some additional data in order to become really useful.  An example of this would be a max length violation with a dynamic input as to the maximum length.  You would certainly like to know in an error message what the string cannot exceed.  Remember, useful error messages are always nice!
Now that we covered that part, let's look at how the code changed from one version to this one.  Refer to the previous post for the code listed.
public static class ResourceMessageManager
     private static string FormatString(string message, params object[] args)
         return string.Format(CultureInfo.InvariantCulture, message, args);
     } // method - FormatString(string, params string[])
     public static string ArgumentNullExceptionMessage
         get { return Strings.ArgumentNullExceptionMessage; }
     } // property - ArgumentNullExceptionMessage
     public static string StringEmptyNullExceptionMessage
         get { return Strings.StringEmptyNullExceptionMessage; }
     } // property - StringEmptyNullExceptionMessage
     public static string StringTooLongExceptionMessage(int maxLength)
         return FormatString(Strings.StringTooLongExceptionMessage, maxLength);
     } // property - StringTooLongExceptionMessage
     public static string UnexpectedTypeExceptionMessage
         get { return Strings.UnexpectedTypeExceptionMessage; }
     } // property - UnexpectedTypeExceptionMessage
     public static string IntOutOfRangeExceptionMessage
         get { return Strings.IntOutOfRangeExceptionMessage; }
     } // property - IntOutOfRangeExceptionMessage
     public static string ZipCodeExceptionMessage
         get { return Strings.ZipCodeExceptionMessage; }
     } // property - ZipCodeExceptionMessage
     public static string EmployeeIDInvalidMessage
         get { return Strings.EmployeeIDInvalidMessage; }
     } // property - EmployeeIDInvalidMessage
} // class - ResourceMessageManager
See, what you can see, it has been greatly simplified.  Now, let's take a look at what has been changed with ArgumentValidatior.  What I did here was add some constant regular expression validations as well as some other functions that would be useful going forward.  Let's take a look at that:
public static class ArgumentValidator
     public const string EmployeeIDExpression = @"^\d{8}";
     public const string ZipCodeExpression = @"^(\d{5}-\d{4}|\d{5}|\d{9})$|^([a-zA-Z]\d[a-zA-Z] \d[a-zA-Z]\d)$";
     public const string SocialSecurityNumberExpression = @"^\d{3}-\d{2}-\d{4}$";
     public const string UrlExpression = @"^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&amp;%\$#_]*)?$";
     public const string PasswordExpression = @"(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,10})$";
     public static bool IsMatch(string input, string pattern)
          CheckForNullReference(pattern, "pattern");
          CheckForNullReference(input, "input");
          return Regex.IsMatch(input, pattern);
     } // method - IsMatch
} // class - ArgumentValidator
There are many regular expressions out there and many good resources to make rock solid expressions.  I'd rather learn these myself instead of relying on the tools already out there because they are always handy in the future.  Should you need to search for some pre-existing ones, Regular Expression Library is not a bad resource.
So, in conclusion, I fixed a few things to make things more ASP.NET 2.0 friendly.  Once you have the validation pattern down, it's quite easy to keep going.
Posted on Wednesday, June 14, 2006 2:45 PM Microsoft , .NET , C# , ASP.NET | Back to top

Comments on this post: .NET Security - Argument Validation Revisited

# re: .NET Security - Argument Validation Revisited
Requesting Gravatar...
These are excellent!

Now, I would love to know how to incorporate these into BizTalk Functoids if at all possible.

Also, whatever happened with the car in your backyard?

Shaun C McDonnell
Portal Dynamics, Orlando, FL
Left by Shaun McDonnell on Jun 14, 2006 3:08 PM

# re: .NET Security - Argument Validation Revisited
Requesting Gravatar...
Well, there are a couple of ways you can do this. You can create a custom library such as this and call it through the "Script Functoid" in which you can call an external assembly that is in the GAC. Or, you can create an external RegEx Functoid yourself much like this example here:

Either way should work for your problem. You could be more evil about it and have inline C#, but that's not really reusable and you'd have to search all over for it. So, that really shouldn't be an option unless for the short run.

I'll probably cover something like that in the very near future as that seems like a pretty interesting idea!

As for the car, well, it's slow progress as I have only just begun cleanup of the backyard. I hope things speed up in the future with that!
Left by Matthew Podwysocki on Jun 14, 2006 3:43 PM

# re: .NET Security - Argument Validation Revisited
Requesting Gravatar...
Great! I'll give it a shot.
You think it might be worth it to inherit from: Microsoft.BizTalk.BaseFunctoid and create a custom functoid?

Shaun McDonnell
Portal Dynamics, Orlando, FL.
Left by Shaun McDonnell on Jun 14, 2006 4:10 PM

# re: .NET Security - Argument Validation Revisited
Requesting Gravatar...

If you are calling an external assembly through the Script Functoid, you do not need to extend the BaseFunctoid class. Only if you were to create a new functoid, then you must go through the joys of extending the BaseFunctoid class and implementing the standard functions.

Left by Matthew Podwysocki on Jun 15, 2006 1:22 PM

Your comment:
 (will show your gravatar)

Copyright © Matthew Podwysocki | Powered by: