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.cs
和 SharedResources.da.resx
放入 Resources 文件夹并使用它将网站语言更改为丹麦语,但它不起作用。使用像 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>
...
在 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.cs
和 SharedResources.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)
{
// ...
}
}
}
所以这是一步一步发生的事情,只是为了提供一个想法:
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
空 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 中):
- 将 SharedResources.cs 放在名为 Resources 的文件夹中。
- 也将 SharedResources.xx-yy.resx 资源文件放在 Resources 文件夹中。
- 在没有 ResourcesPath 选项的情况下调用 services.AddLocalization()。
在尝试了以上所有答案后,我终于得到了我使用的命名空间约定!
如果您的根命名空间中已经有一个点,例如:MyTestApp.WebAPI,那么将虚拟 class 放置在 Resources 文件夹中是行不通的。相反,在项目的根目录中添加一个虚拟 class 并让资源文件位于 Resources 文件夹本身。
参考:https://weblogs.asp.net/ricardoperes/asp-net-core-pitfalls-localization-with-shared-resources
您好,我有一个关于 SharedResources 文件的问题。在这里的教程中浏览了一下:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization,我不确定我是否理解正确。
我应该创建一个 SharedResources.cs
class,但是我应该把它放在哪里,它应该是空的还是我需要用一些数据填充它?
资源文件也是如此,我是否应该创建一个 SharedResources.da.resx
文件并将所有共享字符串放在那里?它应该去哪里?
当我使用 IHtmlLocalizer<SharedResources>
时,我是否只写 @using
并将其指向 SharedResources.cs
所在的命名空间?
我尝试将 SharedResources.cs
和 SharedResources.da.resx
放入 Resources 文件夹并使用它将网站语言更改为丹麦语,但它不起作用。使用像 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>
...
在 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.cs
和 SharedResources.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)
{
// ...
}
}
}
所以这是一步一步发生的事情,只是为了提供一个想法:
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
空 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 中):
- 将 SharedResources.cs 放在名为 Resources 的文件夹中。
- 也将 SharedResources.xx-yy.resx 资源文件放在 Resources 文件夹中。
- 在没有 ResourcesPath 选项的情况下调用 services.AddLocalization()。
在尝试了以上所有答案后,我终于得到了我使用的命名空间约定!
如果您的根命名空间中已经有一个点,例如:MyTestApp.WebAPI,那么将虚拟 class 放置在 Resources 文件夹中是行不通的。相反,在项目的根目录中添加一个虚拟 class 并让资源文件位于 Resources 文件夹本身。
参考:https://weblogs.asp.net/ricardoperes/asp-net-core-pitfalls-localization-with-shared-resources