7

I am trying to override the RequiredAttribute in .net core and does not seem to work on asp.net core 1.1

Here is the test code

public class CustomRequiredAttribute : RequiredAttribute
{
    public CustomRequiredAttribute():base()
    {

    }

    public override string FormatErrorMessage(string name)
    {
        return base.FormatErrorMessage(name);
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        return base.IsValid(value, validationContext);
    }

}

Once used on my model I am expecting the normal result like field is required as I have not customized it yet and just calling base methods.

This does not seem to work as expected and just bypasses the required on both the client and server side.

The purpose of this is to add a validation message pulled from a db to the ErrorMessage property.

ekad
  • 13,718
  • 26
  • 42
  • 44
AliK
  • 677
  • 1
  • 6
  • 23
  • You are not overriding it, you are creating a derived class. Can you show how you are using it? – Klinger Dec 28 '16 at 06:37
  • I am deriving and once it works will override certain methods, i am using it as standard on the model i.e [CustomRequired] public string Name{get;set;} I was hoping as intented it would call the isvalid but breakpoint never hit. – AliK Dec 28 '16 at 06:55
  • 1
    See if this SO helps: http://stackoverflow.com/questions/12573362/extending-the-mvc-requiredattribute – Klinger Dec 28 '16 at 07:03
  • Not really as I am using .net core and the it seems DataAnnotationsModelValidatorProvider does not exist in any of the libraries. – AliK Dec 28 '16 at 07:11
  • When you look at your html, do you see the `data-val-required` attribute? – Klinger Dec 28 '16 at 07:19
  • well it does exist in [Microsoft.AspNetCore.Mvc.DataAnnotations.Internal](https://github.com/aspnet/Mvc/blob/760c8f38678118734399c58c2dac981ea6e47046/src/Microsoft.AspNetCore.Mvc.DataAnnotations/Internal/DataAnnotationsModelValidator.cs#L16), but well.. [internal](http://stackoverflow.com/questions/720647/hiding-namespaces-containing-only-internal-types-in-a-class-library) – Bagus Tesa Dec 28 '16 at 07:20
  • @klinger no it does not and that is exactly what i'm trying to see and then override that once it does exist, but it seems the attributes are not being written to the html and yet if i use the standard attribute from the namespace like[Required(ErrorMessage="test")] that works fine, only when i try using my own is the issue. – AliK Dec 28 '16 at 07:26
  • @Bagus I do know its there but it seems i cannot use it as it does not have the register method as described by that post, I would have assumed this to be a static method on that class. – AliK Dec 28 '16 at 07:28

1 Answers1

3

Your problem is that the ValidationAttributeAdapterProvider, which is the default implementation of IValidationAttributeAdapterProvider, checks for specific types only. Thus, using custom implementations leads to missing "adapter providers", which leads to missing data attributes.

Solution: provide your own implementation of IValidationAttributeAdapterProvider, which can forward to the default implementation for non custom stuff...

public class CustomValidationAttributeAdapterProvider : IValidationAttributeAdapterProvider
{
    private IValidationAttributeAdapterProvider innerProvider = new ValidationAttributeAdapterProvider();

    public IAttributeAdapter GetAttributeAdapter(ValidationAttribute attribute, IStringLocalizer stringLocalizer)
    {
        if (attribute == null)
            throw new ArgumentNullException(nameof(attribute));

        var type = attribute.GetType();

        if (type == typeof(CustomRequiredAttribute))
            return new RequiredAttributeAdapter((RequiredAttribute)attribute, stringLocalizer);

        return innerProvider.GetAttributeAdapter(attribute, stringLocalizer);
    }
}

...and register it as a singleton.

services.AddSingleton<IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();
Axel Heer
  • 1,753
  • 14
  • 21
  • I have tired something similar and I believe this is the right direction to go. – AliK Dec 30 '16 at 00:12
  • @AliK It actually works. Or did I miss to mention some important step? – Axel Heer Dec 31 '16 at 08:33
  • I followed a similar pattern but yes this should work also. The problem is at this point as you know the framework keeps changing so for now its fine lets see what happens with the new releases from MS. – AliK Jan 03 '17 at 00:53