c# - 在所有层中注入当前语言异步安全(ASP.NET Core 3 Mvc)
问题描述
我目前正在编写一个本地化网站(ASP.NET Core 3 Mvc),我设法让它工作并本地化任何东西。
在重构时,我注意到语言污染了我所有的项目层;我必须在需要检索本地化数据的所有方法中将语言从 Web 传递到业务层,然后传递到数据。
我的解决方案具有以下结构
- 常见:横切枚举、扩展和常量
- Web:视图、控制器、身份验证(参考 BusinessLogic、Common)
- BusinessLogic:应用逻辑(参考BusinessLogic、Common)
- 数据:数据检索和操作(参考 BusinessLogic、Common)
现在的语言由以下方式检索
IWbHttpContextAccessor.HttpContext.GetRouteValue("lang") as string
我不想为了获得语言而在所有层中注入这种依赖关系,但我让问题变得更糟。
有没有一种方法可以让我在所有层之间共享当前语言,使用特定的依赖项,安全地与异步方法一起使用?
编辑:如果没有办法在构造函数中注入它,我不想使用 Thread.CurrentThread.CurrentUICulture。这也可以被认为是在异步环境中获取语言的安全方法吗?
EDIT2:我的数据库也是本地化的,所以语言是大多数查询中的一个参数。
这就是我配置本地化的方式
Startup.cs 服务
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new RequestCulture(
culture: "it"
, uiCulture: "it"
);
var supportedCultures = new List<CultureInfo>(){
new CultureInfo("it"), new CultureInfo("en")};
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders.Insert(
0, new RouteCultureProvider(options.DefaultRequestCulture));
});
services.AddScoped<MainLocalizer>();
应用
var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(options.Value);
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern:
"{lang}/{controller}/{action}",
defaults:new{controller = "Account",action = "Login",lang = "it"}
);
});
本地化服务
public class MainLocalizer : StringLocalizer<LocalizedStr>
{
private readonly IStringLocalizer _internalLocalizer;
public MainLocalizer(
IStringLocalizerFactory factory
) : base(factory)
{
_internalLocalizer = new StringLocalizer<LocalizedStr>(factory);
}
public override LocalizedString this[string name, params object[] arguments]
{
get
{
return _internalLocalizer[name, arguments];
}
}
public override LocalizedString this[string name]
{
get
{
return _internalLocalizer[name];
}
}
}
提供者
public class RouteCultureProvider : IRequestCultureProvider
{
private readonly CultureInfo defaultCulture;
private readonly CultureInfo defaultUICulture;
public RouteCultureProvider(RequestCulture requestCulture)
{
this.defaultCulture = requestCulture.Culture;
this.defaultUICulture = requestCulture.UICulture;
}
public Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
{
//Parsing language from url path, which looks like "/en/home/index"
PathString url = httpContext.Request.Path;
// Test any culture in route
if (url.ToString().Length <= 1)
{
// Set default Culture and default UICulture
return Task.FromResult(
new ProviderCultureResult(
this.defaultCulture.TwoLetterISOLanguageName
, this.defaultUICulture.TwoLetterISOLanguageName)
);
}
var parts = httpContext.Request.Path.Value.Split('/');
var culture = parts[1];
// Test if the culture is properly formatted
if (!Regex.IsMatch(culture, @"^[a-z]{2}(-[A-Z]{2})*$"))
{
// Set default Culture and default UICulture
return Task.FromResult(
new ProviderCultureResult(
this.defaultCulture.TwoLetterISOLanguageName
, this.defaultUICulture.TwoLetterISOLanguageName)
);
}
// Set Culture and UICulture from route culture parameter
return Task.FromResult(new ProviderCultureResult(culture, culture));
}
}
解决方案
推荐阅读
- winforms - Windows 窗体 - 报告查看器 14:pdf 大小问题
- sql - 为 Oracle 插入循环
- bash - 如何在 .bashrc 中创建条件别名
- python - 用于谷歌操作的 Python 库
- botframework - 我在哪里可以看到由 bot 框架中的节点 js 代码生成的日志?
- ruby-on-rails - Rails 5 生产应用程序间歇性地使用 nodejs
- system-verilog - 如何从记分板访问序列数据
- python - 损坏的 DAG:[/airflow/dags/a.py] 无法解密 login=None 的“额外”参数,缺少 FERNET_KEY 配置
- c# - 在 Pylon 中加载和保存 pfs 文件
- css - 如何更改 mat-slide-toggle 的颜色属性/覆盖组件的 CSS?