首页 > 解决方案 > 在所有层中注入当前语言异步安全(ASP.NET Core 3 Mvc)

问题描述

我目前正在编写一个本地化网站(ASP.NET Core 3 Mvc),我设法让它工作并本地化任何东西。

在重构时,我注意到语言污染了我所有的项目层;我必须在需要检索本地化数据的所有方法中将语言从 Web 传递到业务层,然后传递到数据。

我的解决方案具有以下结构

现在的语言由以下方式检索

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

标签: c#asp.net-mvcasp.net-corelocalization

解决方案


推荐阅读