Локализация ядра 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
.