Thursday, September 4, 2025

ASP.NET Core 10.0: Custom Validation Support for Minimal APIs

In a previous post, I wrote about ASP.NET Core 10.0: Validation Support for Minimal APIs. In this post, let's go a bit further and see how we can implement custom validations using both ValidationAttribute implementations and implementing the IValidatableObject interface.

ValidationAttribute 


With ValidationAttribute, we can create a Custom attribute with our own custom logic.
public class CustomEmptyValidationAttribute : ValidationAttribute
{
    protected override ValidationResultIsValid(objectvalueValidationContext validationContext)
    {
        if (value is string str && string.IsNullOrEmpty(str))
        {
            return new ValidationResult("Value cannot be null or empty.");
        }

        return ValidationResult.Success;
    }
}
And then we can apply the attribute, something like below for an example.
internal record Employee([CustomEmptyValidation] string Name);

IValidatableObject 


A class/record can implement IValidatableObject and add the validation logic. The validation will kick in as part of model binding.
internal record Employee : IValidatableObject
{
    [Range(1, int.MaxValue)]
    public int Id { getset}

    public string Name { getset}

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (string.IsNullOrEmpty(Name))
        {
            yield return new ValidationResult("Name cannot be null or empty."[nameof(Name)]);
        }
    }
}
Note: Currently there is a bug where IValidatableObject wouldn't trigger validation when there is no validation attribute on a property. (aspnetcore/issues/63394: ASP.NET Core 10.0: Built-in Validation with IValidatableObject)

Hope this helps.

Happy Coding.

Regards,
Jaliya