【问题标题】:Localization based on country in asp.net core 2.1asp.net core 2.1中基于国家的本地化
【发布时间】:2019-12-13 08:08:30
【问题描述】:

我正在尝试根据用户查看我的应用的国家/地区来本地化发回给用户的内容,这意味着他们的国家/地区代码应该是请求 URL 的一部分。例如,如果用户在美国,则所有请求 URL 都应类似于 http://website.com/us/{controller}/{action}。

话虽如此,有没有办法识别用户的原籍国,然后通过将他们的国家/地区 Iso-2-Letter-Code 附加到该 URL 来修改请求 URL,然后使用新 URL 重定向用户。如果请求 URL 有国家代码,那么这个请求修改应该被绕过。

我更喜欢使用或创建一个 asp.net 核心中间件的解决方案,我可以将其附加到 Startup.cs 中的 HTTP 请求管道,或者涉及将新的自定义路由添加到默认 MVC 路由的解决方案。

我们将不胜感激您的帮助和想法。

【问题讨论】:

  • 我在上面回答了您的问题吗?如果是,请将其标记为答案。

标签: c# asp.net-core asp.net-mvc-routing asp.net-core-middleware


【解决方案1】:

.Net 中有一个现有功能,您可以知道来源是什么。它被称为Culture Info

默认情况下,每个客户端都会传入文化信息,或者他们可以指定他们打算使用的当前语言/国家/地区。

我的建议是允许客户在标题名称调用“Accept-Language”中指定文化信息。例如,我在美国并打算使用英语,我会在请求头中发送“en-us”作为请求的一部分。

在后端服务器内部,我会检查这个标头并适当地设置文化信息。

 public class LanguageMessageHandler : DelegatingHandler
{
    private const string LangenUS = "en-US";

    private readonly List<string> _supportedLanguages = new List<string> { LangenUS };

    private bool SetHeaderIfAcceptLanguageMatchesSupportedLanguage(HttpRequestMessage request)
    {
        foreach (var lang in request.Headers.AcceptLanguage)
        {
            if (_supportedLanguages.Contains(lang.Value))
            {
                SetCulture(request, lang.Value);
                return true;
            }
        }

        return false;
    }

    private void SetCulture(HttpRequestMessage request, string lang)
    {
        request.Headers.AcceptLanguage.Clear();
        request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(lang));
        Thread.CurrentThread.CurrentCulture = new CultureInfo(lang);
        Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang);
    }

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (!SetHeaderIfAcceptLanguageMatchesSupportedLanguage(request))
        {
            // Whoops no localization found. Lets try Globalisation
            if (!SetHeaderIfGlobalAcceptLanguageMatchesSupportedLanguage(request))
            {
                // no global or localization found
                SetCulture(request, LangenUS);
            }
        }

        var response = await base.SendAsync(request, cancellationToken);
        return response;
    }

    private bool SetHeaderIfGlobalAcceptLanguageMatchesSupportedLanguage(HttpRequestMessage request)
    {
        foreach (var lang in request.Headers.AcceptLanguage)
        {
            var globalLang = lang.Value.Substring(0, 2);
            if (_supportedLanguages.Any(t => t.StartsWith(globalLang)))
            {
                SetCulture(request, _supportedLanguages.FirstOrDefault(i => i.StartsWith(globalLang)));
                return true;
            }
        }

        return false;
    }
}

【讨论】:

  • 嘿@hongguan,目前手头的问题是特定于国家的,不一定是特定于语言的。您建议的解决方案看起来不错,但不能解决问题。感谢您抽出宝贵时间,感谢您对此的意见。
  • 嘿,是一样的。如果您注意到文化信息,它是专门为您的问题设计的:“LanguageCode-CountryCode”:en-US
  • 快速提问,当前端从两个不同的国家(例如美国和法国)调用 ajax 请求时,服务器会收到两个不同的文化信息,即(en-US 和 fr-FR )。如果答案是肯定的,那我会很高兴的。
  • 我刚刚在肯尼亚用一台电脑进行了测试,我没有得到 en-KE,而是得到了 en-US。我认为它使用了请求计算机中设置的文化信息,大多数人的设置不一定反映他们的实际语言环境。感谢您帮助我就这个问题集思广益。我会将其标记为已接受。如果您有任何机会遇到其他解决方案,请联系我。
  • 这就是为什么大多数应用程序设计会要求位置许可并根据所在国家/地区设置文化信息。这对于您的用例是必要的。但无论如何,文化信息是要走的路。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-24
  • 2020-06-16
  • 1970-01-01
  • 2019-04-11
  • 1970-01-01
相关资源
最近更新 更多