Form validation is a critical aspect of web development, ensuring that user inputs adhere to the required format before processing. In this article, we will explore how to create custom validation attributes in C# using regular expressions to enforce specific input rules for various form fields. We will discuss each custom attribute in detail, along with the regular expression patterns used.


1. AllowOnlyAlphaNumaric

Purpose:

Ensures that input contains only alphanumeric characters, spaces, dots (.), underscores (_), and hyphens (-).

Implementation:

public class AllowOnlyAlphaNumaric: ValidationAttribute
{
public override bool IsValid(object value)
{
string strValue = value as string;
if (string.IsNullOrEmpty(strValue))
{
return true;
}
if (System.Text.RegularExpressions.Regex.IsMatch(strValue, @”^[\sa-zA-Z0-9._-]*$”))
{
return true;
}
else
{
return false;
}
}
}

Regex Pattern

^[\sa-zA-Z0-9._-]*$

  • ^ and $: Ensure the pattern matches the entire string.
  • [\sa-zA-Z0-9._-]*: Matches spaces (\s), letters (a-zA-Z), numbers (0-9), and symbols (., _, -) zero or more times.

Explanation of Regex:

  • ^ and $: Ensure the pattern matches the entire string.
  • \s: Matches spaces.
  • a-zA-Z: Matches uppercase and lowercase letters.
  • 0-9: Matches digits.
  • ._-: Allows dots, underscores, and hyphens.
  • *: Matches zero or more occurrences of the preceding characters.

Use Case

This is ideal for validating usernames or IDs that allow alphanumeric values and a limited set of symbols.


2. ValidateAddress

Purpose:

Validates addresses to include alphanumeric characters, spaces, special characters such as commas, dots, apostrophes, hyphens, slashes, parentheses, and Unicode characters (e.g., accented letters).

Implementation:

public class ValidateAddress : ValidationAttribute
{
public override bool IsValid(object value)
{
string strValue = value as string;
if (string.IsNullOrEmpty(strValue))
{
return true;
}
if (System.Text.RegularExpressions.Regex.IsMatch(strValue, @”^[a-zA-Z0-9\s,.’#\-\/()\u00C0-\u017F]+$”))
{
return true;
}
else
{
return false;
}
}
}

Regex Pattern

^[a-zA-Z0-9\s,.'#\-\/()\u00C0-\u017F]+$

  • Allows characters from Latin-1 Supplement (\u00C0-\u017F) for accents.
  • Includes spaces, numbers, and common symbols such as , . ' # - / ( ).

Explanation of Regex:

  • ,.'#\-\/(): Matches common special characters in addresses.
  • \u00C0-\u017F: Matches Unicode characters in the Latin-1 Supplement and Latin Extended-A blocks.
  • Other parts are similar to the previous regex.

Use Case

Perfect for ensuring valid address entries, including international characters and symbols.


3. SanitizeInputs

Purpose:

Ensures inputs are sanitized by allowing only alphanumeric characters, spaces, and a set of common special characters.

Implementation:

public class SanitizeInputs : ValidationAttribute
{
public override bool IsValid(object value)
{
string inputPattern = @”^[a-zA-Z0-9\s,.’\-@!#$%&*()_+=\/\:;?]+$”;
string strValue = value as string;
if (string.IsNullOrEmpty(strValue))
{
return true;
}
if (System.Text.RegularExpressions.Regex.IsMatch(strValue, inputPattern))
{
return true;
}
else
{
return false;
}
}
}

Regex Pattern

^[a-zA-Z0-9\s,.'\-@!#$%&*()_+=\/:;?]+$

  • Includes additional symbols like @, !, #, %, and others for extended use cases.

Explanation of Regex:

  • Includes characters like @, !, #, %, etc., commonly used in general text inputs.

Use Case

Useful for comment boxes, feedback forms, or any general-purpose text input fields.


4. ValidateOnlyNumeric

Purpose:

Validates that input contains only numeric values.

Implementation:

public class ValidateOnlyNumeric : ValidationAttribute
{
public override bool IsValid(object value)
{
string numericPattern = @”^\d+$”;
string strValue = value as string;
if (string.IsNullOrEmpty(strValue))
{
return true;
}
if (System.Text.RegularExpressions.Regex.IsMatch(strValue, numericPattern))
{
return true;
}
else
{
return false;
}
}
}

Regex Pattern

^\d+$

  • ^\d+$: Matches strings that contain only digits (0-9).

Explanation of Regex:

  • \d: Matches a single digit.
  • +: Ensures one or more digits.

Use Case

Applicable for validating numeric fields such as quantity, IDs, or PIN codes.


5. ValidateEmail

Purpose:

Validates email addresses based on common email formats.

Implementation:

public class ValidateEmail : ValidationAttribute
{
public override bool IsValid(object value)
{
string emailPattern = @”^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$”;
string strValue = value as string;
if (string.IsNullOrEmpty(strValue))
{
return true;
}
if (System.Text.RegularExpressions.Regex.IsMatch(strValue, emailPattern))
{
return true;
}
else
{
return false;
}
}
}

Regex Pattern

^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

  • Local part: ^[a-zA-Z0-9._%+-]+
  • Domain part: @[a-zA-Z0-9.-]+
  • TLD: \.[a-zA-Z]{2,}$

Explanation of Regex:

  • Allows alphanumeric characters and special characters before the @ symbol.
  • Ensures a domain name format after the @.

Use Case

Critical for validating email addresses in login or registration forms.


6. ValidateContactNo

Purpose:

Validates phone numbers, including optional country codes, separators, and parentheses.

Implementation:

public class ValidateContactNo : ValidationAttribute
{
public override bool IsValid(object value)
{
string phonePattern = @”^\+?[0-9]{1,3}?[-. ]?(\(?[0-9]{1,4}\)?)?[-. ]?[0-9]{1,4}[-. ]?[0-9]{1,9}$”;
string strValue = value as string;
if (string.IsNullOrEmpty(strValue))
{
return true;
}
if (System.Text.RegularExpressions.Regex.IsMatch(strValue, phonePattern))
{
return true;
}
else
{
return false;
}
}
}

Regex Pattern

^\+?[0-9]{1,3}?[-. ]?(\(?[0-9]{1,4}\)?)?[-. ]?[0-9]{1,4}[-. ]?[0-9]{1,9}$

  • Supports optional country codes (+).
  • Allows separators like -, ., or spaces.

Explanation of Regex:

  • Handles various phone number formats, including optional country codes (+), separators (-, ., ), and area codes in parentheses.

Use Case

Essential for validating phone numbers across various regions.


7. ValidateDate

Purpose:

Validates dates in DD-MM-YYYY format.

Implementation:

public class ValidateDate : ValidationAttribute
{
public override bool IsValid(object value)
{
string ddMMyyyyPattern = @”^(0[1-9]|[12]\d|3[01])-(0[1-9]|1[0-2])-(19|20)\d\d$”;
string strValue = value as string;
if (string.IsNullOrEmpty(strValue))
{
return true;
}
if (System.Text.RegularExpressions.Regex.IsMatch(strValue, ddMMyyyyPattern))
{
return true;
}
else
{
return false;
}
}
}

Regex Pattern

^(0[1-9]|[12]\d|3[01])-(0[1-9]|1[0-2])-(19|20)\d\d$

  • Matches day (01-31), month (01-12), and year (1900-2099).

Explanation of Regex:

  • Validates day, month, and year ranges for proper date formatting.

Use Case

Used for validating date inputs in forms requiring a DD-MM-YYYY format.


Here’s how you can use these attributes in an ASP.NET model:

public class UserForm
{

[SanitizeInputs]
[AllowOnlyAlphaNumaric]
public string Username { get; set; }

[SanitizeInputs]

[ValidateEmail]
public string Email { get; set; }

[SanitizeInputs]

[ValidateAddress]
public string Address { get; set; }

[SanitizeInputs]

[ValidateOnlyNumeric]
public string ZipCode { get; set; }

[SanitizeInputs]

[ValidateDate]
public DateTime BirthDate { get; set; }
}


Conclusion

These custom validation attributes ensure data integrity and prevent malicious input, enhancing your application’s security and user experience. Leveraging regex in C# provides a scalable and customizable way to validate various input types efficiently. With these examples, you can create a robust validation layer tailored to your application’s needs.