Search code examples
c#asp.net-core.net-coredata-annotationsasp.net-core-7.0

Multiple ways of writing DataAnnotations custom validators


I wrote a custom DataAnnotations validator (for client and server):

public class CustomAttribute : ValidationAttribute, IClientModelValidator { /* ... */ }

However the docs show an alternate approach, using three classes:

public class CustomAttribute : ValidationAttribute { /* ... */ }

public class CustomAttributeAdapter : AttributeAdapterBase<CustomAttribute> { /* ... */ }

public class CustomAttributeAdapterProvider : IValidationAttributeAdapterProvider { /* ... */ }

And one must also register the provider during startup:

services.AddSingleton<IValidationAttributeAdapterProvider, CustomAttributeAdapterProvider>();

My simpler way works, and I don't even register it in the container.

Why do the docs show that more complicated approach? Is there some extra feature or behaviour which my way lacks?


Solution

  • My simpler way works, and I don't even register it in the container.

    Why do the docs show that more complicated approach? Is there some extra feature or behaviour which my way lacks?

    From the doc you referenced, it lists the difference of using custom validation attribute that inherits from ValidationAttribute and IClientModelValidator with using additional AttributeAdapter and ValidationAttributeAdapterProvider:

    • Create a class that derives from AttributeAdapterBase<TAttribute> and a class that implements IValidationAttributeAdapterProvider, and register your attribute and its adapter in DI. This method follows the single responsibility principle in that server-related and client-related validation code is in separate classes. The adapter also has the advantage that since it's registered in DI, other services in DI are available to it if needed.

    • Implement IClientModelValidator in your ValidationAttribute class. This method might be appropriate if the attribute doesn't do any server-side validation and doesn't need any services from DI.