Локализация сообщений об ошибках основной привязки ASP.NET

Я использую ASP.NET Core и пытаюсь локализовать приложение. Мне удалось использовать новые основные ресурсы asp.net для локализации контроллеров и представлений и старых ресурсов для локализации сообщений об ошибках для проверки модели. Однако, когда сообщение об ошибке не связано с аннотацией поля модели (например, "Обязательный" ), а данные для привязки к модели неверны (например, текст, где ожидается число), я получаю ошибку, как показано ниже, не удалось локализовать:

"Значение 'abc' недопустимо для ID."

Когда я ввожу abc для свойства ID в View, так как привязка модели не может быть выполнена к полю, и она показывает сообщение проверки рядом с полем, говоря: "Значение" abc "недействительно для идентификатора.". Вот класс, который я использую:

public class Country : IHasID
{
    public int ID { get; set; }

    [Required(ErrorMessageResourceType = typeof(L.Val),
    ErrorMessageResourceName = "NameR")]
    [MaxLength(100, ErrorMessageResourceType = typeof(L.Val), 
    ErrorMessageResourceName = "Max")]
    public string Name { get; set; }

    /*Some other properties*/
}

Подобные проблемы, которые я нашел в Интернете, были либо нацелены на более старую версию asp.net, либо не помогли мне решить проблему.

Ответ 1

Чтобы настроить сообщения об ошибках привязки модели фреймворка, вам нужно установить собственные средства доступа для разных средств доступа к сообщениям об ошибках ModelBindingMessageProvider.

Пример

Здесь вы можете скачать полный исходный код того, что описано в этом посте. Репозиторий содержит пример для ASP.NET Core 2.0 (VS 2017.3) и ASP.NET Core 1.1 (VS 2015):

Также здесь вы можете увидеть пример, в прямом эфире:

Сообщения об ошибках по умолчанию

Это сообщения об ошибках по умолчанию, которые структура показывает при сбое привязки модели к свойству:

MissingBindRequiredValueAccessor    A value for the '{0}' property was not provided.
MissingKeyOrValueAccessor           A value is required.
ValueMustNotBeNullAccessor          The value '{0}' is invalid. 
AttemptedValueIsInvalidAccessor     The value '{0}' is not valid for {1}.
UnknownValueIsInvalidAccessor       The supplied value is invalid for {0}.
ValueIsInvalidAccessor              The value '{0}' is invalid.
ValueMustBeANumberAccessor          The field {0} must be a number.

В дополнение к вышеприведенным сообщениям в ASP.NET Core 2.0 также есть следующие сообщения:

MissingRequestBodyRequiredValueAccessor       A non-empty request body is required.
NonPropertyAttemptedValueIsInvalidAccessor    The value '{0}' is not valid.
NonPropertyUnknownValueIsInvalidAccessor      The supplied value is invalid.
NonPropertyValueMustBeANumberAccessor         The field must be a number.

Локализуйте сообщения об ошибках привязки базовой модели ASP.NET

Чтобы локализовать сообщения об ошибках привязки модели ASP.NET Core, выполните следующие действия:

  1. Создать файл ресурсов - создайте файл ресурсов в папке "Ресурсы" в своем решении и назовите файл ModelBindingMessages.fa.resx. Имя может быть любым, но мы будем использовать его для создания локализатора. В этом примере я использовал fa (персидскую) культуру.

  2. Добавить ключи ресурсов - откройте файл ресурсов и добавьте ключи и значения, которые вы хотите использовать для локализации сообщений об ошибках. Я использовал ключи и значения, как на картинке ниже:

    enter image description here

    Ключи, которые я использовал, похожи на оригинальные сообщения, за исключением ключа для ValueMustNotBeNull, который был таким же, как ValueIsInvalid, поэтому я использовал значение Null недействительно. для этого.

  3. Настройка параметров - В методе ConfigureServices при добавлении Mvc настройте его параметры для установки средств доступа к сообщениям для ModelBindingMessageProvider:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddLocalization(options => { options.ResourcesPath = "Resources"; });
        services.AddMvc(options =>
        {
            var F = services.BuildServiceProvider().GetService<IStringLocalizerFactory>();
            var L = F.Create("ModelBindingMessages", "AspNetCoreLocalizationSample");
            options.ModelBindingMessageProvider.ValueIsInvalidAccessor =
                (x) => L["The value '{0}' is invalid.", x];
            options.ModelBindingMessageProvider.ValueMustBeANumberAccessor =
                (x) => L["The field {0} must be a number.", x];
            options.ModelBindingMessageProvider.MissingBindRequiredValueAccessor =
                (x) => L["A value for the '{0}' property was not provided.", x];
            options.ModelBindingMessageProvider.AttemptedValueIsInvalidAccessor =
                (x, y) => L["The value '{0}' is not valid for {1}.", x, y];
            options.ModelBindingMessageProvider.MissingKeyOrValueAccessor =
                () => L["A value is required."];
            options.ModelBindingMessageProvider.UnknownValueIsInvalidAccessor =
                (x) => L["The supplied value is invalid for {0}.", x];
            options.ModelBindingMessageProvider.ValueMustNotBeNullAccessor =
                (x) => L["Null value is invalid.", x];
        })
        .AddDataAnnotationsLocalization()
        .AddViewLocalization();
        services.Configure<RequestLocalizationOptions>(options =>
        {
            var supportedCultures = new[]{new CultureInfo("en"), new CultureInfo("fa")};
            options.DefaultRequestCulture = new RequestCulture("en", "en");
            options.SupportedCultures = supportedCultures;
            options.SupportedUICultures = supportedCultures;
        });
    }
    

    Также добавьте этот код в начале метода Configure:

    var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("fa") };
    app.UseRequestLocalization(new RequestLocalizationOptions()
    {
        DefaultRequestCulture = new RequestCulture(new CultureInfo("en")),
        SupportedCultures = supportedCultures,
        SupportedUICultures = supportedCultures
    });
    

Важное примечание для ASP.NET Core 2.0

В ASP.NET Core 2.0 свойства поставщика сообщений привязки модели получили только для чтения, но метод установки для каждого свойства был добавлен.

Например, чтобы установить ValueIsInvalidAccessor, вы должны использовать SetValueIsInvalidAccessor() метод таким образом:

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