2 minute read

When developing applications in C#, it is crucial to ensure that string fields are valid to maintain data integrity and avoid issues caused by invalid input. One common requirement is to validate that a string is not only filled out but also not composed entirely of whitespace. While basic checks can be done manually, creating a reusable custom validation attribute streamlines this process. This blog post will guide you through creating such a custom validation attribute in C#.

Understanding the Limitation of Basic Validation

In many scenarios, simply checking if a string is null or empty is not sufficient. For example, a user input like “ “ (spaces) should be considered invalid, but basic checks like string.IsNullOrEmpty will not catch this case. To handle this, we need a more robust validation mechanism.

Creating a Custom Validation Attribute

To address this, we can create a custom validation attribute that ensures a string is not null, empty, or composed solely of whitespace characters.

Step 1: Define the Custom Attribute

First, we create a new class that inherits from ValidationAttribute and override the IsValid method to implement our custom logic.

using System;
using System.ComponentModel.DataAnnotations;

public class NotEmptyOrWhitespaceAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
        {
            return new ValidationResult("The field cannot be empty or consist only of whitespace characters.");
        }

        return ValidationResult.Success;
    }
}

In this class:

  • We check if the value is null or a string that consists only of whitespace using string.IsNullOrWhiteSpace.
  • If the value is invalid, we return a ValidationResult with a custom error message.
  • If the value is valid, we return ValidationResult.Success.

Step 2: Apply the Custom Attribute to Your Class

Now that we have our custom validation attribute, we can use it in our class definitions. Here’s how you can apply it to a sample class.

public class MyData
{
    [NotEmptyOrWhitespace]
    public string MyField { get; set; }
}

With the NotEmptyOrWhitespace attribute in place, any instance of MyData will ensure that MyField is not null, empty, or just whitespace when validated.

Using the Custom Attribute

To use the custom attribute, you typically validate the class instance before processing it. Here’s an example of how to do this in a console application.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

public class Program
{
    public static void Main()
    {
        var data = new MyData { MyField = "   " }; // Invalid input
        var context = new ValidationContext(data);
        var results = new List<ValidationResult>();

        bool isValid = Validator.TryValidateObject(data, context, results, true);

        if (!isValid)
        {
            foreach (var validationResult in results)
            {
                Console.WriteLine(validationResult.ErrorMessage);
            }
        }
        else
        {
            Console.WriteLine("Valid input");
        }
    }
}

In this example:

  • We create an instance of MyData with an invalid MyField value (only spaces).
  • We create a ValidationContext for the instance and a list to hold validation results.
  • We call Validator.TryValidateObject to perform the validation.
  • If the input is invalid, we print the validation error messages.

Conclusion

Custom validation attributes in C# provide a powerful way to enforce specific rules for your data. By creating a NotEmptyOrWhitespace attribute, we ensure that string fields are neither null, empty, nor composed solely of whitespace characters, thus enhancing the robustness of our data validation.

Implementing such custom attributes is straightforward and offers greater control over the validation process, ensuring that your application handles user input correctly and securely. This approach can be particularly beneficial in applications where data integrity is paramount.

Leave a comment