High quality input validation is essential to many, if not all systems that we write. It doesn’t matter whether we’re validating user input in a WPF or Silverlight application, checking data transfer objects passed into a service layer or verifying the information in a JSON packet submitted by REST, validation is essential.
Lately, I’ve been working with a bunch of code that looks like this:
var results = new List<ValidationResult>();
if (string.IsNullOrWhitespace(myPerson.FullName))
{
results.Add(
new ValidationResult(
"FullName", "Full Name is a mandatory field"));
}
else if (myPerson.FullName.Length > 100)
{
results.Add(
new ValidationResult(
"FullName", "Full Name must be 100 characters or less."));
}
if (string.IsNullOrWhitespace(myPerson.KnownAs))
{
results.Add(
new ValidationResult(
"KnownAs", "Known As is a mandatory field"));
}
else if (myPerson.KnownAs.Length > 50)
{
results.Add(
new ValidationResult(
"KnownAs", "Known As must be 50 characters or less."));
}
This code works - but it is ugly. The code is verbose and repetitive - the mechanics of building ValidationResult
items and adding them to the results list swamp the actual checks being made.
Inspired in part by an Ivan Towlson presentation at Microsoft TechEd 2011 in New
Zealand, I’ve got a prototype going in Visual Studio 2010 that looks like this:
var results = new List<ValidationResult>();
using (dynamic check = new ValidationContext(myPerson, results))
{
check.FullName( mandatory: true, maxlength: 100);
check.KnownAs( mandatory: true, maxlength: 50);
}
How on earth does this work?
-
The
ValidationContext
class provides an ambient context for validation that gathers up validation results in the background, without any need to pass around the list itself. -
Leveraging the new dynamic keyword in C# 4 allows the
ValidationContext
to behave as though it has a method for each property declared onmyPerson
. The named parameters passed to these dynamic methods specify the requested checks.
What do you think? Does this qualify as evil code, or merely expressive?
Should I turn this prototype into an actual library and make it available for download?
Update: Ivan Towlson has responded with a blog entry of his own: Dynamic interfaces in C#
Comments
blog comments powered by Disqus