Using Localized Resources with Enterprise Library 3 Validation
page 6 of 9
by Brian Mains
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 38619/ 162

Phone Number Validator

As I mentioned earlier, phone numbers have a lot of challenges.  Phone number digits, in certain countries, shift when the area code has more or less digits.  Phone number area codes could have many different amounts of digits.  There are long-distance codes or out-of-country codes that pose an additional problem.  In addition, phone numbers may contain dashes, but this could also be a space; however, the phone number validation also allows no spacing as well.  The solution right now is to ignore long-distance and specialty codes and target the widest audience of home and business phone numbers.

To counter additional illegal numbers with all of this variation, two length properties are defined: a minimum and maximum length that the phone number range must be between or a validation error is added.

Listing 4

protected virtual int MaximumLength
{
  get
  {
    return int.Parse(ValidationResources.PhoneNumberMaximumLength);
  }
}
 
protected virtual int MinimumLength
{
  get
  {
    return int.Parse(ValidationResources.PhoneNumberMinimumLength);
  }
}
 
protected virtual string PhoneNumberAreaCodeOnlyRegex
{
  get
  {
    return ValidationResources.PhoneNumberAreaCodeOnlyRegex;
  }
}
 
protected virtual string PhoneNumberRegex
{
  get
  {
    return ValidationResources.PhoneNumberRegex;
  }
}

The phone number validation regular expression looks like this: ^((\([2-9][0-8][0-9]\) ?)|([2-9][0-8][0-9][- ]))[2-9][0-9]{2}[- ][0-9]{4}$.  The ^ and $ denote the beginning and end.  Also note that it allows a format of (XXX) XXX-XXXX or XXX-XXX-XXXX.  Lastly, note that with area code rules state that the first digit is 2-9, the second is 0-8, and the third is 0-9, which is similar to the exchange format.  Also, there is an area code regular expression for getting and parsing only the area code, which is used to extract the digits from the area code and match them against the accepted area code list (if provided), which will be discussed in the next section.

These properties can be overloaded if inherited from.  All of these properties use resource strings, as well as the default messages.

Listing 5

protected override string DefaultMessageTemplate
{
  get
  {
    return ValidationResources.PhoneNumberValidator_DefaultMessage;
  }
}
 
protected virtual string DefaultInvalidAreaCodeMessageTemplate
{
  get
  {
    return
      ValidationResources.PhoneNumberValidator_InvalidAreaCodeDefaultMessage;
  }
}
 
protected virtual string DefaultInvalidLengthMessageTemplate
{
  get
  {
    return ValidationResources.PhoneNumberValidator_InvalidLengthDefaultMessage;
  }
}

To provide added functionality, this validator contains an array list of area codes, which can enforce which area codes a phone number can be in.  So, for instance, you can limit the input to a specific range of area code numbers, instead of allowing any area code.

Listing 6

public List < string > AcceptedAreaCodes
{
  get
  {
    if (_acceptedAreaCodes == null)
      _acceptedAreaCodes = new List < string > ();
    return _acceptedAreaCodes;
  }
}

Similarly, if no area codes are in the list, the zip code can be enforced or not enforced through another property called EnforceZipCode.

Listing 7

public bool EnforceAreaCode
{
  get
  {
    return _enforceAreaCode;
  }
  set
  {
    _enforceAreaCode = value;
  }

}
To construct the object, there are many overloads available to provide area codes, specify whether area codes are enforced, and the other default properties (like message and tag); because that is straightforward, I will not show those here.

The validation is not overly complex; however, it does require a lot of thought as to how it will work.  First, we have to determine how detailed error messages are rendered specific to the problem with the data.  This is why there are three default error messages, to expose all of the problems that there could be.  The method that actually renders a message is an overloaded version of GetMessage, which takes a message key (one of the several constant values) and renders the appropriate default or overridden message.

Listing 8

private const string INVALID_AREA_CODE_MESSAGE_KEY = "Area Code";
private const string INVALID_LENGTH_MESSAGE_KEY = "Length";
 
protected virtual string GetMessage(string objectToValidate, string key, string
  messageKey)
{
  if (!string.IsNullOrEmpty(this.DefaultInvalidAreaCodeMessageTemplate) &&
    messageKey == INVALID_LENGTH_MESSAGE_KEY)
    return string.Format(CultureInfo.CurrentCulture,
      this.DefaultInvalidAreaCodeMessageTemplate, objectToValidate, key);
  else if (!string.IsNullOrEmpty(this.DefaultInvalidLengthMessageTemplate) &&
    messageKey == INVALID_AREA_CODE_MESSAGE_KEY)
  return string.Format(CultureInfo.CurrentCulture,
    this.DefaultInvalidLengthMessageTemplate, new object[]
  {
    objectToValidate, key, this.MinimumLength, this.MaximumLength
  }
  );
  else
    return this.GetMessage(objectToValidate, key);
}

The call to it is as simple as below, which we will also see more about later.

Listing 9

this.GetMessage(objectToValidate, key, INVALID_AREA_CODE_MESSAGE_KEY)

Another method is also helpful to use when validating area codes.  For instance, is the character returned from the regular expression an area code character or something like the "(" in the area code of "(724)."  To determine this, the validation method loops through each character and validates the char to determine if it is valid and calls this method.

Listing 10

protected virtual bool IsValidAreaCodeValue(char value)
{
  return Char.IsDigit(value);
}

The validation method, DoValidate, processes the text in several ways.  First, if enforce area code is set to false, it does not validate the area code specifically.  Let us walk through the current validation process.  I validate the length to ensure it is valid.  If not, a length-specific message is rendered to the screen.

Listing 11

if (objectToValidate.Length < this.MinimumLength || objectToValidate.Length >
  this.MaximumLength)
  base.LogValidationResult(validationResults, this.GetMessage(objectToValidate,
    key, INVALID_LENGTH_MESSAGE_KEY), currentTarget, key);

Note the call to the overloaded GetMessage method.  Next, if enforcing the area code and we have a valid regular expression (some countries will not have one because they don’t area codes), we process it specially to ensure it is valid or exists within the range of area codes provided in the list.

Listing 12

if (this.EnforceAreaCode && !string.IsNullOrEmpty
  (this.PhoneNumberAreaCodeOnlyRegex))
{
  if (!Regex.IsMatch(objectToValidate, this.PhoneNumberAreaCodeOnlyRegex))
    base.LogValidationResult(validationResults, this.GetMessage
      (objectToValidate, key, INVALID_AREA_CODE_MESSAGE_KEY), currentTarget,
      key);
  else if (this.AcceptedAreaCodes.Count > 0)
  {
    string areaCodeText = Regex.Match(objectToValidate,
      this.PhoneNumberAreaCodeOnlyRegex).Value;
    string areaCode = string.Empty;
 
    foreach (char pos in areaCodeText)
    {
      if (this.IsValidAreaCodeValue(pos))
        areaCode += pos.ToString();
    }
 
    if (!this.AcceptedAreaCodes.Contains(areaCode))
      base.LogValidationResult(validationResults, this.GetMessage
        (objectToValidate, key, INVALID_AREA_CODE_MESSAGE_KEY), currentTarget,
        key);
  }
}

Lastly, the whole number if validated against a regular expression to ensure that it is correct and meets a specified regular expression match.

Listing 13

if (!Regex.IsMatch(objectToValidate, this.PhoneNumberRegex))
  base.LogValidationResult(validationResults, this.GetMessage(objectToValidate,
    key), currentTarget, key);

View Entire Article

User Comments

Title: Great Help   
Name: Tarun
Date: 2007-04-26 6:04:28 AM
Comment:
well its really a good help regarding the Enterprise Library 3.0.

I want to same thing for Exception Application block in which i have to localized the exception messages.

Can any one please help me about it.

Thanks.

Regards
Tarun

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2019 ASPAlliance.com  |  Page Processed at 2019-12-07 2:06:48 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search