4

In ASP.NET CORE 1.1 it was possible to localize model binding error messages using a resource file and configure its options to set message accessors for ModelBindingMessageProvider in the Startup.cs like

services.AddMvc(options =>
{
    var F = services.BuildServiceProvider().GetService<IStringLocalizerFactory>();
    var L = F.Create("ModelBindingMessages", null);
    options.ModelBindingMessageProvider.ValueIsInvalidAccessor =
        (x) => L["The value '{0}' is invalid."];

as shown here: ASP.NET Core Model Binding Error Messages Localization and here: https://blogs.msdn.microsoft.com/mvpawardprogram/2017/05/09/aspnetcore-mvc-error-message/

In ASP.NET CORE 2.0 I receive an error message on all of the ModelBindingMessageProvider's properties

options.ModelBindingMessageProvider.ValueIsInvalidAccessor 

is readonly

How can these messages be localized in ASP.NET CORE 2.0

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
Fritz
  • 43
  • 2
  • 5
  • I added VS 2017 ASP.NET Core 2.0 sample to the [repository](https://github.com/r-aghaei/AspNetCoreLocalizationSample). – Reza Aghaei Aug 31 '17 at 21:19

3 Answers3

2

In ASP.NET Core 2.0, model binding message provider properties have got read only, but a setter method for each property has been added.

So if you follow the example of my linked post, to set ValueIsInvalidAccessor, you should use SetValueIsInvalidAccessor method this way:

options.ModelBindingMessageProvider.SetValueIsInvalidAccessor (
    (x) => L["The value '{0}' is invalid."]);

Sample Project

I added the sample project for ASP.NET CORE 2.0 in the following repository:

Default Error Messages:

  • MissingBindRequiredValueAccessor: A value for the '{0}' property was not provided.
  • MissingKeyOrValueAccessor: A value is required.
  • MissingRequestBodyRequiredValueAccessor: A non-empty request body is required.
  • ValueMustNotBeNullAccessor: The value '{0}' is invalid.
  • AttemptedValueIsInvalidAccessor: The value '{0}' is not valid for {1}.
  • NonPropertyAttemptedValueIsInvalidAccessor: The value '{0}' is not valid.
  • UnknownValueIsInvalidAccessor: The supplied value is invalid for {0}.
  • NonPropertyUnknownValueIsInvalidAccessor: The supplied value is invalid.
  • ValueIsInvalidAccessor: The value '{0}' is invalid.
  • ValueMustBeANumberAccessor: The field {0} must be a number.
  • NonPropertyValueMustBeANumberAccessor: The field must be a number.
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • 1
    The "A value is required." translation does not work for me, all other do. If I change your model from int Id to string Id and put a [Required] above, I always receive the English error instead of the translation. Does it work on your side? – Fritz Oct 22 '17 at 20:19
  • It's not the problem of default model binder error messages. It's because of `Required` attribute. When you use data annotations validation attributes, you need to localize them as well. – Reza Aghaei Oct 22 '17 at 20:27
  • 1
    To solve the problem, do the same thing that I've done for `StringLength` attribute. Add `[Required(ErrorMessage = "{0} is Required.")]` above the property. Then in `Models.SampleModel.fa.resx` add `{0} is Required.` having value `فیلد {0} الزامی است.`. – Reza Aghaei Oct 22 '17 at 20:40
  • Thank you. I new this option, but was talking about the default error message using [Required] only, without any Errormessage in brackets. This one seems to be hard to get translated. – Fritz Oct 25 '17 at 13:23
  • You're welcome :) This is the way that error message localization for data annotations work. I believe it's not hard to translate `{0} is Required.` ;) – Reza Aghaei Oct 25 '17 at 13:25
  • Just curious - where do the default messages come from? I searched entire GitHub but found only resource names, such as `Resources.FormatModelBinding_MissingBindRequiredMember` but I could not find the specific text strings anywhere. – JustAMartin Jul 11 '19 at 12:12
  • @JustAMartin Take a look at xml comment (summary) of properties in [Resources.Designer.cs](https://github.com/aspnet/AspNetCore/blob/c565386a3ed135560bc2e9017aa54a950b4e35dd/src/Mvc/Mvc.Core/src/Properties/Resources.Designer.cs). This file is auto-generated from [Resources.Resx](https://github.com/aspnet/AspNetCore/blob/c565386a3ed135560bc2e9017aa54a950b4e35dd/src/Mvc/Mvc.Core/src/Resources.resx), take a look at data tags. – Reza Aghaei Jul 11 '19 at 14:58
1

I also ran into this. These setters were replaced with methods such as SetValueIsInvalidAccessor, the change is described here: https://github.com/aspnet/Announcements/issues/240

Neme
  • 492
  • 3
  • 14
0

you could use this configuration for localize mvc core error messages :

public class SomeMvcOptionsSetup : Microsoft.Extensions.Options.IConfigureOptions<Microsoft.AspNetCore.Mvc.MvcOptions>
{
    private readonly Microsoft.Extensions.Localization.IStringLocalizer _resourceLocalizer;

    public SomeMvcOptionsSetup()
    {
    }

    public SomeMvcOptionsSetup(Microsoft.Extensions.Localization.IStringLocalizerFactory stringLocalizerFactory)
    {
        _resourceLocalizer = stringLocalizerFactory.Create(baseName:"ResourceClassName",location:"ResourceNameSpace");
    }

    public void Configure(Microsoft.AspNetCore.Mvc.MvcOptions options)
    {
        options.ModelBindingMessageProvider.SetValueIsInvalidAccessor((x) =>
        {
            if (_resourceLocalizer == null)
            {
                return "Custom Error Message";
            }

            return _resourceLocalizer["Specific Resource Key In Resource File"]; 
        });

        options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor((x) =>
        {
            if (_resourceLocalizer == null)
            {
                return "Value Can not be null....";
            }
            return _resourceLocalizer["ResourceKeyValueCanNotBeNull"];
        });

  .
  .
  .


    }
}

Then, add the following to your Startup.ConfigureServices(...) method:

 services.TryAddEnumerable(
ServiceDescriptor.Transient<IConfigureOptions<MvcOptions>,SomeMvcOptionsSetup >());

Please see this link

Iraj
  • 1,492
  • 5
  • 18
  • 42