Intereting Posts
WPF: привязка к свойству объекта; что происходит, когда объект изменяется? Windows Phone 8 Получить снимки из телефонной библиотеки Как я могу наиболее эффективно использовать несколько ядер для коротких вычислений в .NET? Как сгенерировать WSDL-файл с веб-службы C # Преобразование столбца с отформатированным временем в excel в C # DateTime Как отказаться от всех обработчиков из события для определенного classа в C #? Должен ли шифрованный / обфускационный код поставщика HASP? Excel RoundUp против .NET Math.Round Как захватить колесо мыши на панели? Максимальная длина байта ? Почему C # не делает «простого» вывода типа для дженериков? Вставка пробелов между символами в списке ASP.net получает доступ к главной переменной страницы через страницу содержимого Кнопка Winforms Изображение с обратной связью правой кнопки мыши (кнопка «Показать» в нажатом состоянии) Как открыть журнал событий программно?

Локализация RequiredAttribute в ASP.NET Core 2.0

Я борюсь с локализацией в своем новом проекте .NET Core. У меня есть 2 проекта:

  • Проект DataAccess с моделями и DataAnnotations (например, RequiredAttribute)
  • Веб-проект с просмотром MVC и т. Д.

Мое желание состоит в том, чтобы локализовать все атрибуты проверки в глобальном масштабе в одном месте, чтобы иметь аналогичное поведение, такое как MVC 5. Возможно ли это?

Я не хочу иметь отдельные языковые файлы для моделей / представлений и т. Д.

Документация Microsoft не очень понятна при использовании файла SharedResources.resx с локализованными сообщениями DataAnnotation.

В MVC 5 я не позаботился об этом. Мне нужно было установить язык на свой язык, и все было в порядке.

Я попытался установить имя ErrorMessageResourceName и ErrorMessageResourceType в мое имя ресурса общего ресурса «Strings.resx» и «Strings.de.resx» в проекте DataAccess:

[Required(ErrorMessageResourceName = "RequiredAttribute_ValidationError", ErrorMessageResourceType = typeof(Strings))] 

Я также попробовал имя параметра RequiredAttribute_ValidationError – но он не работает.

Я уже добавил .AddDataAnnotationsLocalization() в Startup.cs – но, похоже, ничего не делает.

Я прочитал несколько статей, но я не мог найти причину, почему он не работает.

EDIT: Что я до сих пор:

1.) Класс LocService

  public class LocService { private readonly IStringLocalizer _localizer; public LocService(IStringLocalizerFactory factory) { _localizer = factory.Create(typeof(Strings)); } public LocalizedString GetLocalizedHtmlString(string key) { return _localizer[key]; } } 

2.) Добавлена ​​папка «Ресурсы» с помощью Strings.cs (пустой class с фиктивным конструктором)

3.) Добавлен файл Strings.de-DE.resx с одним элементом «RequiredAttribute_ValidationError»

4.) Изменено мое Startup.cs

 public void ConfigureServices(IServiceCollection services) { services.AddTransient(); services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddSingleton(); services.AddLocalization(options => options.ResourcesPath = "Resources"); services.AddMvc() .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver()) .AddDataAnnotationsLocalization( options => { options.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(Strings)); }); services.Configure( opts => { var supportedCultures = new List { new CultureInfo("de-DE"), }; opts.DefaultRequestCulture = new RequestCulture("de-DE"); // Formatting numbers, dates, etc. opts.SupportedCultures = supportedCultures; // UI strings that we have localized. opts.SupportedUICultures = supportedCultures; }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseBrowserLink(); app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } var locOptions = app.ApplicationServices.GetService<IOptions>(); app.UseRequestLocalization(locOptions.Value); app.UseStaticFiles(); app.UseMvcWithDefaultRoute(); } 

Я следил за инструкциями здесь, но он не работает: https://damienbod.com/2017/11/01/shared-localization-in-asp-net-core-mvc/

Имейте в виду, что мои модели хранятся в отдельном проекте.

Как отмечает @Sven в своем комментарии к ответу Цзэна, он по-прежнему требует, чтобы вы указали явный ErrorMessage , который становится довольно утомительным.

Проблема возникает из логики ValidationAttributeAdapter.GetErrorMessage() использует, чтобы решить, использовать ли предоставленный IStringLocalizer или нет. Для решения этой проблемы я использую следующее решение:

  1. Создайте пользовательскую реализацию IValidationAttributeAdapterProvider которая использует параметр ValidationAttributeAdapterProvider по умолчанию:

     public class LocalizedValidationAttributeAdapterProvider : IValidationAttributeAdapterProvider { private readonly ValidationAttributeAdapterProvider _originalProvider = new ValidationAttributeAdapterProvider(); public IAttributeAdapter GetAttributeAdapter(ValidationAttribute attribute, IStringLocalizer stringLocalizer) { attribute.ErrorMessage = attribute.GetType().Name.Replace("Attribute", string.Empty); if (attribute is DataTypeAttribute dataTypeAttribute) attribute.ErrorMessage += "_" + dataTypeAttribute.DataType; return _originalProvider.GetAttributeAdapter(attribute, stringLocalizer); } } 
  2. Зарегистрируйте адаптер в Startup.ConfigureServices() Перед вызовом AddMvc() :

     services.AddSingleton(); 

Я предпочитаю использовать «более строгие» имена ресурсов на основе фактических атрибутов, поэтому приведенный выше код будет искать имена ресурсов, такие как «Обязательный» и «DataType_Password», но это, конечно же, можно настроить разными способами.

Если вы предпочитаете имена ресурсов на основе сообщений по умолчанию из атрибутов, вы можете написать что-то вроде:

 attribute.ErrorMessage = attribute.FormatErrorMessage("{0}"); 

Я попытался установить имя ErrorMessageResourceName и ErrorMessageResourceType в мое имя ресурса общего ресурса «Strings.resx» и «Strings.de.resx» в проекте DataAccess:

  [Required(ErrorMessageResourceName = "RequiredAttribute_ValidationError", ErrorMessageResourceType = typeof(Strings))] 

Я также попробовал имя параметра RequiredAttribute_ValidationError – но он не работает.

Вы были на правильном пути, но вам необязательно устанавливать свойства ErrorMessageResourceName / ErrorMessageResourceType .

Мы могли видеть в исходном коде ValidationAttributeAdapter , условия использования _stringLocalizer _stringLocalizer – это когда ErrorMessage не является null а ErrorMessageResourceName / ErrorMessageResourceTypenull .

Другими словами, когда вы не ErrorMessage никаких свойств или только ErrorMessage . Таким образом, простой [Required] должен просто работать (см. Источник, который передается конструктору базовых classов).

Теперь, когда мы смотрим файл ресурсов DataAnnotations, мы видим, что имя установлено в «RequiredAttribute_ValidationError», и требуется значение «Поле {0]». который является английским переводом по умолчанию.

Теперь, если вы используете «RequiredAttribute_ValidationError» с переводом на немецкий язык в вашем «Strings.de-DE.resx» (или просто Strings.resx в качестве резервного), он должен работать с исправленным пространством имен из комментариев.

Поэтому, используя указанную выше конфигурацию и строки из репозитория GitHub, вы сможете сделать работу локализации без дополнительных атрибутов.

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

Сообщения об ошибках для стандартных атрибутов данных:

 [Required] [Range] [StringLength] [Compare] ...etc. 

Сообщения об ошибках для ModelBinding:

 ValueIsInvalid ValueMustNotBeNull PropertyValueMustBeANumber ...etc. 

и сообщения об ошибках Identity:

 DuplicateEmail DuplicateRoleName InvalidUserName PasswordRequiresLower PasswordRequiresUpper ...etc 

каждый должен быть настроен в файле запуска. Следует также рассмотреть дополнительную проверку на стороне клиента.

вы можете проверить эти статьи для получения более подробной информации, в нем есть демонстрационный пример и демонстрационный проект на GitHub:

Разработка мультикультурного веб-приложения: http://www.ziyad.info/en/articles/10-Developing_Multicultural_Web_Application

Локализация аннотаций данных: http://www.ziyad.info/ru/articles/16-Localizing_DataAnnotations

Локализация сообщений об ошибках ModelBinding: http://www.ziyad.info/ru/articles/18-Localizing_ModelBinding_Error_Messages

Локализация сообщений об ошибках идентификации: http://www.ziyad.info/ru/articles/20-Localizing_Identity_Error_Messages

и проверка на стороне клиента: http://ziyad.info/ru/articles/19-Configuring_Client_Side_Validation

Надеюсь, поможет 🙂