Localize `Required` annotation in French implicitl

2020-07-13 08:20发布

问题:

TLDR; How to get the behaviour of

[Required(ErrorMessage = "Le champ {0} est obligatoire")]

while only writing

[Required]

As I understand it the documentation does not provide a way to implicitly localize a given set of DataAnnotations.

I would like to have the error messages for annotations such as Required and StringLength be over-rideable without touching others such as Display and without the need to explicitly specify the translation using the ErrorMessage attribute.

note: I only need to have the messages translated in French, so there is no need for the solution to be bound to the request's language.

I tried the following:

From this GitHub thread

In the Startup.cs

services.AddMvc(options => options.ModelBindingMessageProvider.AttemptedValueIsInvalidAccessor =
    (value, name) => $"Hmm, '{value}' is not a valid value for '{name}'."));

Gives me the following error

Property or indexer 'DefaultModelBindingMessageProvider.AttemptedValueIsInvalidAccessor' cannot be assigned to -- it is read only

And I could not find any property that might work as a setter for this object.


From this SO answer

In the Startup.cs services.AddSingleton();

and create a class like follow

public class LocalizedValidationAttributeAdapterProvider : IValidationAttributeAdapterProvider
{
    private readonly ValidationAttributeAdapterProvider _originalProvider = new ValidationAttributeAdapterProvider();

    public IAttributeAdapter GetAttributeAdapter(ValidationAttribute attribute, IStringLocalizer stringLocalizer)
    {
        /* override message */
    }
}

But this only captured the DataType annotation

回答1:

In .Net Core 2, the Accessor properties in ModelBindingMessageProvider are read-only, but you can still set them by using the Set...Accessor() methods. Here's code similar to what I'm using, with thanks to the answer to ASP.NET Core Model Binding Error Messages Localization.

public static class ModelBindingConfig
{
    public static void Localize(MvcOptions opts)
    {
        opts.ModelBindingMessageProvider.SetMissingBindRequiredValueAccessor(
            x => string.Format("A value for the '{0}' property was not provided.", x)
        );

        opts.ModelBindingMessageProvider.SetMissingKeyOrValueAccessor(
            () => "A value is required."
        );
    }
}


// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    // ...

    services.AddMvc(
        opts =>
        {
            ModelBindingConfig.Localize(opts);
        })
        .AddViewLocalization()
        .AddDataAnnotationsLocalization();
}