Custom ASP.NET validation attributes
ASP.NET validation attributes is a great way to validate C# properties in different ways, both client & server side. Let’s look at how we can create our own validation attributes.
I use custom validation attributes all the time, for instance to validate:
- E-mail addresses
- Postal codes
- Social security numbers
- URLs
These could to some extent be validated with regular expressions, but some may require a deeper level of validation than just looking at string format.
Custom validation attributes can perform basic regex validation client-side, then perform a more thorough validation server-side if needed.
Let’s look at some examples:
class EmailAddressAttribute : RegularExpressionAttribute
{
EmailAddressAttribute()
: base(@"^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$") { }
override bool IsValid(object value)
{
if (value == null || value.ToString().IsNullOrEmpty())
return false;
return base.IsValid(value);
}
}
class SwedishPostalCodeAttribute : RegularExpressionAttribute
{
SwedishPostalCodeAttribute(bool optionalSpace = false)
: base(optionalSpace ? "^\\d{3}\\ ?\\d{2}$" : "^\\d{5}$") { }
override bool IsValid(object value)
{
if (value == null || value.ToString().IsNullOrEmpty())
return false;
return base.IsValid(value);
}
}
class SwedishSsnAttribute : RegularExpressionAttribute
{
SwedishSsnAttribute()
: base("^\\d{6}-?\\d{4}$") { }
override bool IsValid(object value)
{
if (value == null || value.ToString().IsNullOrEmpty())
return false;
//Remove possible dash
var noDash = value.ToString().Replace("-", "");
//Verify the Luhn algorithm
var sum = 0;
for (var i = 0; i < 9; i++)
{
var tmpInt = int.Parse(noDash[i].ToString());
tmpInt = tmpInt * (((i + 1) % 2) + 1);
sum += (tmpInt > 9) ? tmpInt - 9 : tmpInt;
sum = (sum > 10) ? sum - 10 : sum;
}
//Verify the check digit
return (10 - sum) == int.Parse(noDash[9].ToString());
}
}
class UrlAttribute : RegularExpressionAttribute
{
UrlAttribute()
: base(@"^(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?") { }
override bool IsValid(object value)
{
if (value == null || value.ToString().IsNullOrEmpty())
return false;
return base.IsValid(value);
}
}
As you can see, the e-mail, postal code and url attributes only use a regular expression as well as null/empty conditions, while the social security number attribute does a bit more.
With this approach, RegularExpressionAttribute
can be validated client-side and a second validation can then take place server-side, when the user posts the form.
This makes it possible to gather all validation in one place. If you need to use the regex as a separate value, it can be accessed with the Pattern
property of the validation attribute.
Discussions & More
Please share any ideas, feedback or comments you may have in the Disqus section below, or by replying on Twitter or Mastodon.
If you found this text interesting, make sure to follow me on Twitter and Mastodon for more content like this, and to be notified when new content is published.
If you like & want to support my work, please consider sponsoring me on GitHub Sponsors.