请让我全面回答这个问题,并描述我是如何在阅读.net core源代码后得出解决方案的。
在进一步描述之前,请先使用NuGet安装此软件包Microsoft.Extensions.Localization
正如大家可能还记得的那样,在asp.net full framework中,切换文化非常简单。
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
在.NET Core中,文化(culture)不再与当前线程绑定。ASP.NET Core引擎具有管道(pipeline),我们可以向该管道添加不同的中间件(MiddleWares),因此
RequestLocalizationMiddleware是用于处理本地化的中间件类。我们可能会有多个提供程序,因此它将遍历所有的文化提供程序,例如
QueryStringRequestCultureProvider、
CookieRequestCultureProvider和
AcceptLanguageHeaderRequestCultureProvider等等。
一旦请求本地化中间件从第一个提供程序获取到当前区域设置,则它将忽略其他提供程序并将请求传递给管道中的下一个中间件,因此提供程序列表中的顺序非常重要。
我个人更喜欢将文化存储在浏览器cookie中,因此,由于
CookieRequestCultureProvider不是列表中第一个文化提供程序,所以我将其移到列表的顶部。在Startup.cs的ConfigureServices中配置如下:
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("fa-IR"),
new CultureInfo("de-DE")
};
options.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
var defaultCookieRequestProvider =
options.RequestCultureProviders.FirstOrDefault(rcp =>
rcp.GetType() == typeof(CookieRequestCultureProvider));
if (defaultCookieRequestProvider != null)
options.RequestCultureProviders.Remove(defaultCookieRequestProvider);
options.RequestCultureProviders.Insert(0,
new CookieRequestCultureProvider()
{
CookieName = ".AspNetCore.Culture",
Options = options
});
});
让我描述一下上面的代码,我们应用程序的默认语言环境是en-US,我们只支持英语、波斯语和德语,因此,如果浏览器的语言环境与这三种语言不同,或者您设置的语言是其他语言,则应用程序必须切换到默认语言环境。在上述代码中,我只是从列表中删除了CookieCultureProvider,并将其作为第一个提供程序添加到列表中(*我已经解释了为什么它必须是第一个*)。默认的CookieName对我有效,如果您想要更改它,可以这样做。
不要忘记在Startup.cs中的Configure(IApplicationBuilder app, IHostingEnvironment env)下面添加以下代码。
var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(options.Value);
目前为止还不错。要拥有资源文件,您必须指定资源的路径。我单独在Web项目根路径中为Controller、Views、ViewModels和SharedResources指定资源,层次结构如下所示。
|-Resoures
|---Controllers
|---Views
|---Models
|---SharedResource.resx
|---SharedResource.fa-IR.resx
|---SharedResource.de-DE.resx
请记住,对于SharedResource,在Web项目根路径中创建一个同名的空类,即在其中创建一个带有相同名称的类 SharedResource.cs 。
将以下代码片段添加到 Startup.cs 中以指定资源路径和其他内容。
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
AddViewLocalization(
LanguageViewLocationExpanderFormat.Suffix,
opts => { opts.ResourcesPath = "Resources/Views"; }) // this line is not required, it is just for more clarification
.AddDataAnnotationsLocalization();
例如,当您在控制器中注入IStringLocalizer时,需要在Resources>Controllers文件夹中有相应的资源文件(即HomeController.resx、HomeController.fa-IR.resx、HomeController.de-DE.resx)。我们还可以通过 . (点)分隔路径,即文件名Resources/Controllers/HomeController.resx可以是Resource / Controllers.HomeController.resx中的文件,您必须将IViewLocalizer注入视图中,以便在视图中进行本地化,相应地,您必须在Resources / Views文件夹中为Views准备资源文件。对于ViewModels,由于我们命名了Models文件夹,请将所有ViewModels放在Web项目根路径中预先创建的名为Models的文件夹中,如果文件夹具有其他名称或您更喜欢其他名称,请不要忘记在Resource文件夹下重命名Models文件夹。然后,您什么也不需要做,只需注释模型,例如,使用[DisplayName("User Emailaddress")]注释ViewModel属性,然后在模型内对应的资源文件中创建相应的资源(文件名必须与模型类名匹配),并使用相同的键("User Emailaddress")。
让我们完成我们已经开始的内容,我指的是 CookieRequestCultureProvider 。如我之前所说,我更喜欢将其存储在cookie中,但这有点棘手,因为 cookie解析与您预期的有点不同。只需在要更改文化的位置添加下面的代码,只需将preferedCulture替换为您的文化偏好即可。
var preferedCulture = "fa-IR";
if (HttpContext.Response.Cookies.ContainsKey(".AspNetCore.Culture"))
{
HttpContext.Response.Cookies.Delete(".AspNetCore.Culture");
}
HttpContext.Response.Cookies.Append(".AspNetCore.Culture",
$"c={preferedCulture}|uic={preferedCulture}", new CookieOptions {Expires = DateTime.UtcNow.AddYears(1)});
我们开始吧,我们的sp.net核心Web应用现在已本地化 :)