It seems to me that ASP.NET Core MVC no longer supports DataAnnotationsModelValidatorProvider.RegisterAdapter . The solution I discovered is this:
Suppose I want to change Validator for RequiredAttribute to my own validator adapter ( MyRequiredAttributeAdaptor ), change the default error message for EmailAddressAttribute and change the source of the localized error messages for "CompareAttribute" to my own message.
1- Creating a custom ValidationAttributeAdapterProvider
using Microsoft.AspNetCore.Mvc.DataAnnotations; using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal; using Microsoft.Extensions.Localization; using System.ComponentModel.DataAnnotations; public class CustomValidationAttributeAdapterProvider : ValidationAttributeAdapterProvider, IValidationAttributeAdapterProvider { public CustomValidationAttributeAdapterProvider() { } IAttributeAdapter IValidationAttributeAdapterProvider.GetAttributeAdapter( ValidationAttribute attribute, IStringLocalizer stringLocalizer) { IAttributeAdapter adapter; if (attribute is RequiredAttribute) { adapter = new MyRequiredAttributeAdaptor((RequiredAttribute) attribute, stringLocalizer); } else if (attribute is EmailAddressAttribute) { attribute.ErrorMessage = "Invalid Email Address."; adapter = base.GetAttributeAdapter(attribute, stringLocalizer); } else if (attribute is CompareAttribute) { attribute.ErrorMessageResourceName = "InvalidCompare"; attribute.ErrorMessageResourceType = typeof(Resources.ValidationMessages); var theNewattribute = attribute as CompareAttribute; adapter = new CompareAttributeAdapter(theNewattribute, stringLocalizer); } else { adapter = base.GetAttributeAdapter(attribute, stringLocalizer); } return adapter; } }
2- Add CustomValidationAttributeAdapterProvider to run:
Add the following line to public void ConfigureServices(IServiceCollection services) in Startup.cs:
services.AddSingleton <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider> ();
Here is the MyRequiredAttributeAdaptor adapter:
using System; using System.ComponentModel.DataAnnotations; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.Extensions.Localization; using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal; public class MyRequiredAttributeAdaptor : AttributeAdapterBase<RequiredAttribute> { public MyRequiredAttributeAdaptor(RequiredAttribute attribute, IStringLocalizer stringLocalizer) : base(attribute, stringLocalizer) { } public override void AddValidation(ClientModelValidationContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } MergeAttribute(context.Attributes, "data-val", "true"); MergeAttribute(context.Attributes, "data-val-required", GetErrorMessage(context)); }
Recommendations:
1- See Microsoft Example: Entropy Project: This is a great example for various .NET Core features. In this question: see the MinLengthSixAttribute implementation in the Mvc.LocalizationSample.Web sample:
https://github.com/aspnet/Entropy/tree/dev/samples/Mvc.LocalizationSample.Web
2- To see how attribute adapters work, see asp.Microsoft.AspNetCore.Mvc.DataAnnotations on github:
https://github.com/aspnet/Mvc/tree/dev/src/Microsoft.AspNetCore.Mvc.DataAnnotations