Локализация ядра ASP.NET с помощью SharedResources

Привет, у меня есть вопрос о файле SharedResources. В этом учебном пособии рассмотрено следующее: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization, и я не уверен, правильно ли я понял.

Я должен создать класс SharedResources.cs, но куда его поместить, и должен ли он быть пустым или мне нужно заполнить его некоторыми данными?

То же самое касается файла ресурсов, должен ли я создать файл SharedResources.da.resx и разместить все мои общие строки? Куда он должен идти?

И когда я использую IHtmlLocalizer<SharedResources>, просто пишу @using и указываю его на пространство имен, в котором находится SharedResources.cs?

Я попытался положить SharedResources.cs и SharedResources.da.resx в папку "Ресурсы" и использовать его для изменения языка сайта на датский язык, но он не работает. Использование выделенного файла ресурсов, такого как Index.da.resx и IViewLocalizer, отлично работает, но IHtmlLocalizer<SharedResources>, похоже, не работает.

Когда я посмотрел пример проекта, связанный в нижней части страницы, я не нашел места, где используется SharedResources, было бы здорово, если бы кто-то обновил его примером.

Вот как я пытался это сделать:

Views/Home/Index.cshtml:

@using Funkipedia.Resources
@using Microsoft.AspNetCore.Mvc.Localization
@inject IHtmlLocalizer<Shared> SharedLocalizer
...
<p>@SharedLocalizer["Hei"]</p>
...

В верхней части ConfigureServices в Startup.cs:

services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
  .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
  .AddDataAnnotationsLocalization();

В верхней части Configure в Startup.cs:

var supportedCultures = new List<CultureInfo>
{
       new CultureInfo("nb-NO"),
       new CultureInfo("sv-SE"),
       new CultureInfo("da-DK")
};

app.UseRequestLocalization(new RequestLocalizationOptions
{
       DefaultRequestCulture = new RequestCulture("nb-NO"),
       SupportedCultures = supportedCultures,
       SupportedUICultures = supportedCultures
});

Папка ресурсов содержит пустой класс с именем Shared.cs и Shared.da.resx, который содержит общие строки. Возможно, мне нужно изменить его имя на SharedResources.cs и SharedResources.da.resx?

Ответ 1

Хорошо, после некоторых копаний вокруг и даже больше проб и ошибок я нашел ответы на свои вопросы и получил все, чтобы работать. Вот что я нашел:

Я должен создать класс SharedResources.cs, но куда его поместить, и должен ли он быть пустым или мне нужно заполнить его некоторыми данными?

ANSWER: SharedResources.cs может быть помещен в корневую папку проекта или в папку "Ресурсы", но самое главное, что пространство имен должно быть установлено в корень проекта. В моем случае namespace Funkipedia. И ему не нужно содержать какие-либо данные, просто объявление класса.

То же самое касается файла ресурсов, должен ли я создать файл SharedResources.da.resx и поместить туда все мои общие строки? Куда он должен идти?

ANSWER: Да, вам нужно создать файл ресурсов, который будет так же, как и файл .cs, и нужен, который будет помещен в папку "Ресурсы".

И когда я использую IHtmlLocalizer<SharedResources>, просто пишу @using и указываю его на пространство имен, в котором находится SharedResources.cs?

ОТВЕТ: Когда дело доходит до использования IHtmlLocalizer и/или IStringLocalizer, вам нужно написать это в верхней части файла .cshtml:

@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Localization
@inject IViewLocalizer Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@inject IHtmlLocalizer<SharedResources> SharedHtmlLocalizer

Обратите внимание, что @using Microsoft.Extensions.Localization требуется, только если вы используете IStringLocalizer

Я надеюсь, что это поможет другим, кто может быть новичком в файлах ресурсов и локализации приложений ASP.NET Core.

Ответ 2

Я хотел бы добавить настройку, которая работает и для моей команды. Это основано на том же принципе, что и ваш (конечно), но я считаю, что он обеспечивает некоторую гибкость в расположении файлов, поскольку он не заставляет вас размещать связанные с ресурсами файлы в корне проекта.

Я понимаю, что IStringLocalizer<T> имеет концепцию placeholder Type, чье полное имя будет преобразовано в относительный путь и использовано для поиска фактического файла ресурсов. Для этого преобразования также используется информация из LocalizationOptions.ResourcesPath, если таковая имеется.

Скажите, что у вас есть:

// in ProjectRoot\Startup.cs

services.AddLocalization(opts =>
{
  opts.ResourcesPath = "Localized";
});

// in ProjectRoot\Area\Whatever\SomeClass.cs

namespace Com.Company.Project.Area.Whatever
{
  public class SomeClass
  {
    public SomeClass(IStringLocalizer<SomeClass> localizer)
    {
      // ...
    }
  }
}

Итак, что происходит, шаг за шагом, просто чтобы дать идею:

  • SomeClass фамилия: Com.Company.Project.Area.Whatever.SomeClass
  • преобразуйте это в путь .resx файла: Com\Company\Project\Area\Whatever\SomeClass.resx
  • содержащий ResourcesPath содержимое: Localized\Com\Company\Project\Area\Whatever\SomeClass.resx

То, что фактический путь, в котором будут просматриваться файлы ресурсов.

Итак, в целом вы можете поместить свой SharedResources.cs пустой класс, где хотите, до тех пор, пока вы реплицируете его полное имя как путь в папке ResourcesPath в корне проекта.

В примере:

\
--Area
  --Whatever
    --SomeClass.cs
--Localized
  --Com
    --Company
      --Project
        --Area
          --Whatever
            --SomeClass.resx
            --SomeClass.fr.resx
            --SomeClass.da.resx

Под обложкой требуется это дерево каталогов, потому что классы, созданные из файла resx, берут свое пространство имен из дерева каталогов, а также потому, что строковый локализатор не будет разделять корневое пространство имен при префиксеровании типа заполнителя с помощью ResourcesPath.