Regular expressions offer programmers an easy way to validate strings in many programming languages. In this post, I will show how you can add regular expression validation capabilities to Dynamics CRM 2011 processes.
Regular expressions overview
First, for those who may not be familiar with regular expressions, let me offer a brief example of what kinds of problems they can solve. Let's say you need to validate a U.S. or Canadian phone number in C#. These numbers are governed by the North American Numbering Plan (NANP) and can be formatted as 1-###-###-####. Because all of the countries in the NANP share the same 1 "country code," that is typically omitted from phone numbers when they are stored in a database for domestic use. If you use the string methods in C#, a basic validation function might look something like this:
bool ValPhoneNumber(string numberToValidate)
{
//NANP phone numbers should be entered in this format 334-867-5309
//create an array of the three sets of digits
string[] phoneParts = numberToValidate.Split("-".ToCharArray());
//if we have more or less than three sets, return false
if (phoneParts.Length != 3)
{
return false;
}
else
{
//if the sets aren't the correct length, return false
if ((phoneParts[0].Length != 3) || (phoneParts[1].Length != 3) || (phoneParts[2].Length != 4))
{
return false;
}
else
{
//if any of the sets can't be parsed as an integer, return false
for (int i = 0; i < 3; i++)
{
int parseResult;
if (!Int32.TryParse(phoneParts[i], out parseResult))
{
return false;
}
}
}
}
//if we got here after all our previous checks, return true
return true;
}
You'll note that code is extremely brittle. U.S. phone numbers are also sometimes represented in the form of (###) ###-#### or ###.###.####. To change to one of those formats from ###-###-#### or to add them as alternative options would be a non-trivial exercise.
On the other hand, if we use C#'s regular expression engine, which is found in the System.Text.RegularExpressions namespace, we can reduce the validation code to:
bool ValPhoneNumber(string numberToValidate)
{
//define the pattern
string matchPattern = "^[2-9]\d{2}-d{4}-d{4}$";
//do the match
Match match = Regex.Match(numberToValidate, matchPattern, RegexOptions.IgnoreCase);
//return the status of the match (true or false)
return match.Success;
}
In this method, we define a pattern and then we run the regular expression engine against the supplied string input using the pattern. This is a relatively simple pattern to match all strings in the format of ###-###-#### that start with a number other than 1 or 0, which are invalid starting digits for NANP numbers. If we want to handle additional phone number patterns, we can add them to the match pattern using a regular expression OR operator. For example, "dog|cat" matches either "dog" or "cat." For more information on regular expressions in C#, I suggest you take a look at the MSDN .Net regular expression article here.
Regular expression uses in Microsoft Dynamics CRM
Now that you understand what regular expressions can do, take a minute to consider how you could use them to enhance the functionality of Dynamics CRM workflows and dialogs. Here are a couple of simple ideas, but I'll bet you can come up with plenty that are applicable to your own situation:
- When certain types of contacts are created, a workflow adds them to a marketing list. Use a regular expression to verify phone numbers are valid before contacts are added.
- Use a regular expression validator to scan the text of e-mails when they enter a particular queue. If the pattern matches, create a case tied to the e-mail.
The bad news is that there's no out-of-the-box support for regular expressions in Dynamics CRM 2011 processes, so you'll have to roll your own custom workflow activity to handle it. The good news is that it's easy, and I can show you how in just a few lines of code.
The code
The custom workflow activity should do the following:
- Accept a string to validate and a regular expression match pattern via input arguments. Strictly speaking, you could hardcode the match pattern, but using an input argument gives you maximum flexibility.
- Evaluate the regular expression.
- Return the result of the match via an output argument.
Specifically, there are only two things we need to do. First we need to set up our input and output parameters:
[Input("String to validate")]
public InArgument<String> StringToValidate { get; set; }
[Input("Match pattern")]
public InArgument<String> MatchPattern { get; set; }
[Output("Valid")]
public OutArgument<int> Valid { get; set; }
You'll note that the Valid output parameter is an integer instead of a boolean. I decided to use 0 for false and 1 for true because CRM 2011 dialogs do not support boolean variables in the process definition. This way I can declare a variable up front and then set it to the validator activity's output.
Next, we add the following lines to our Execute method to actually evaluate the input string and the supplied regular expression:
//do the match
Match match = Regex.Match(StringToValidate.Get(executionContext), MatchPattern.Get(executionContext),RegexOptions.IgnoreCase);
//did we match anything?
if (match.Success)
{
Valid.Set(executionContext, 1);
}
else
{
Valid.Set(executionContext, 0);
}
You can download the code for this custom workflow activity here. When I register the assembly in my CRM instance, I am then able to set up validation in a dialog like in the following screenshot:
How do you handle advanced validations in your Dynamics CRM processes? Can you think of some other interesting uses for regular expressions? Let us know in the comments!
A version of this post was originally published on the HP Enterprise Services Application Services blog.