ASP.NET 在 SharedResources 的帮助下进行核心本地化

ASP.NET Core Localization with help of SharedResources

您好,我有一个关于 SharedResources 文件的问题。在这里的教程中浏览了一下:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization,我不确定我是否理解正确。

我应该创建一个 SharedResources.cs class,但是我应该把它放在哪里,它应该是空的还是我需要用一些数据填充它?

资源文件也是如此,我是否应该创建一个 SharedResources.da.resx 文件并将所有共享字符串放在那里?它应该去哪里?

当我使用 IHtmlLocalizer<SharedResources> 时,我是否只写 @using 并将其指向 SharedResources.cs 所在的命名空间?

我尝试将 SharedResources.csSharedResources.da.resx 放入 Resources 文件夹并使用它将网站语言更改为丹麦语,但它不起作用。使用像 Index.da.resxIViewLocalizer 这样的专用资源文件工作正常,但 IHtmlLocalizer<SharedResources> 似乎不起作用。

当我查看页面底部链接的示例项目时,我没有找到任何使用 SharedResources 的地方,如果有人用一个示例更新它就太好了。

我是这样尝试的:

Views/Home/Index.cshtml:

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

在 Startup.cs 中的 ConfigureServices 顶部:

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

在 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
});

Resources 文件夹包含名为 Shared.cs 的空 class 和包含共享字符串的 Shared.da.resx。我是否需要将其名称更改为 SharedResources.csSharedResources.da.resx

好的,经过一番深入研究和更多的反复试验后,我找到了我的问题的答案并且一切正常。这是我的发现:

我应该创建一个 SharedResources.cs class,但是我应该把它放在哪里,它应该是空的还是我需要用一些数据填充它?

回答: SharedResources.cs可以放在项目的根目录下,也可以放在Resources目录下,但最重要的是namespace要设置在根目录下的项目。就我而言 namespace Funkipedia。而且它不需要包含任何数据,只需要 class 声明。

资源文件也是如此,我是否应该创建一个 SharedResources.da.resx 文件并将所有共享字符串放在那里?它应该去哪里?

答案:是的,您需要创建一个与 .cs 文件同名的资源文件,并且 需要 将其放入在资源文件夹中。

当我使用 IHtmlLocalizer<SharedResources> 时,我是否只写 @using 并将其指向 SharedResources.cs 所在的命名空间?

答案: 在视图中使用 IHtmlLocalizer and/or IStringLocalizer 时,您需要在 .cshtml 文件:

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

请注意,仅当您使用 IStringLocalizer

时才需要 @using Microsoft.Extensions.Localization

我希望这会帮助那些可能不熟悉 ASP.NET 核心应用程序的资源文件和本地化的其他人。

我也想添加适用于我的团队的设置。它基于与您相同的原则(当然),但我相信它允许您的文件位置更加灵活,因为它不会强制您将与资源相关的文件放在项目根目录中。

我的理解是IStringLocalizer<T>有一个placeholderType的概念,它的fullname会被转换成相对路径,用于查找实际资源文件。要进行此转换,它还使用来自 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)
    {
      // ...
    }
  }
}

所以这是一步一步发生的事情,只是为了提供一个想法:

  1. SomeClass全名:Com.Company.Project.Area.Whatever.SomeClass
  2. 将其转换为 .resx 文件路径:Com\Company\Project\Area\Whatever\SomeClass.resx
  3. 前缀为 ResourcesPath 内容:Localized\Com\Company\Project\Area\Whatever\SomeClass.resx

这是查找资源文件的实际路径。

所以,总而言之,你可以把你的 SharedResources.cs 空 class 放在任何你想要的地方,只要你复制它的全名作为项目根目录下 ResourcesPath 文件夹下的路径.

示例中:

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

在幕后,需要该目录树,因为从 resx 文件生成的 classes 将从目录树中获取它们的命名空间,还因为字符串本地化器将 not 在占位符类型前面加上 ResourcesPath.

时去除根命名空间

以下是对我有用的(在 ASP.NET Core 2.0 中):

  1. 将 SharedResources.cs 放在名为 Resources 的文件夹中。
  2. 也将 SharedResources.xx-yy.resx 资源文件放在 Resources 文件夹中。
  3. 在没有 ResourcesPath 选项的情况下调用 services.AddLocalization()。

在尝试了以上所有答案后,我终于得到了我使用的命名空间约定!

如果您的根命名空间中已经有一个点,例如:MyTestApp.WebAPI,那么将虚拟 class 放置在 Resources 文件夹中是行不通的。相反,在项目的根目录中添加一个虚拟 class 并让资源文件位于 Resources 文件夹本身。

参考:https://weblogs.asp.net/ricardoperes/asp-net-core-pitfalls-localization-with-shared-resources