Create your own Validationattribute in ASP.NET Core

4/27/2023
3 minute read

In this small blog post, I will show you how to create your own Validation attribute in ASP.NET Core to tailor-made your validation rules.

Validation attributes

So that we are on the same page, ASP.NET Core offers a set of validation attributes that can be used to validate the data that is being sent to the server. These attributes are used to decorate the properties of the model class. This also applies to Blazor if you want for form validation. Here is a small example:

public class Person
{
    [Required]
    public string Name { get; set; }

    [Required]
    [Range(18, 99)]
    public int Age { get; set; }
}

Required means that Name has to be set and not empty (or full of whitespaces). Range means that Age has to be between 18 and 99. If you want to know more about the validation attributes, you can check out the documentation. So there are a number of attributes that can be used to validate the data. But what if you want to validate the data in a more complex way? For example, you have a model that contains a DateTime object that should be in the future? Here is where we can hook in and write our own validation attributes.

Custom validation attributes

It is quite straightforward to write your own validation attributes. You can inherit from the ValidationAttribute class and override the IsValid method. This method takes an object as a parameter and returns a boolean. The object is the value that is being validated. In the example below, we are validating that the DateTime object is in the future. If it is, we return true, otherwise we return false and add an error to the ValidationContext object. The ValidationContext object contains the model that is being validated and the DisplayName of the property that is being validated. This is used to display the error message to the user.

public class FutureDateAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value is DateTime date)
        {
            if (date > DateTime.Now)
            {
                return ValidationResult.Success;
            }
        }

        return new ValidationResult($"The {validationContext.DisplayName} field must be a future date.");
    }
}

The usage of this attribute is the same as the other validation attributes. You can decorate the property with the attribute and you are good to go. Here is an example:

public class BlogPost
{
    [FutureDate]
    public DateTime ScheduleDate { get; set; }
}

Of course, you can add further configuration, like the DateTime has to be UTC, or add an optional error message. Here is how you can do that:

public class FutureDateAttribute : ValidationAttribute
{
    public bool Utc { get; set; } = true;

    protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
    {
        if (value is null)
        {
            return ValidationResult.Success;
        }

        var now = UseUtc ? DateTime.UtcNow : DateTime.Now;

        return (DateTime)value <= now
            ? new ValidationResult("The selected date must be in the future.")
            : ValidationResult.Success;
    }
}

Here the usage of the attribute:

public class BlogPost
{
    [FutureDate(Utc = false)]
    public DateTime ScheduleDate { get; set; }
}

Conclusion

In this article, we have seen how we can write our own validation attributes. This is useful if you want to validate the data in a more complex way. For example, you want to validate that a DateTime object is in the future.

ASP.NET Core - Why async await is useful

Did you ever wonder why you "should" use async and await in your ASP.NET Core applications? Most probably, you heard something about performance. And there is some truth to it, but not in the way you might think.

So let's discuss this with smaller examples.

Building a Minimal ASP.NET Core clone

In this article, we will build a minimal version of what ASP.NET Core does - yes, you read right. We will create a very simplistic clone of ASP.NET Core to discuss how the whole thing works. Beginning with a simple console application, we will add the necessary components to make it work as a web server. Bonus points for our own middleware pipeline and dependency injection.

How to write your own cron Job scheduler in ASP.NET Core (like Quartz, Hangfire, ...)

In this blog post we will discover how to write your own small task scheduler / job scheduler with cron notation in ASP.NET Core. You might know similar approaches under the name of Quartz or Hangfire.

With the help of BackgroundService we will build our own, lightweight version of it.

An error has occurred. This application may no longer respond until reloaded. Reload x