asp.net 核心 2.1 中基于国家/地区的本地化
Localization based on country in asp.net core 2.1
我正在尝试根据用户正在查看我的应用程序的国家/地区对发送回用户的内容进行本地化,这意味着他们的国家/地区代码应该是请求的一部分 url。例如,如果用户在美国,所有请求 URL 应该是 http://website.com/us/{controller}/{action}.
话虽如此,有没有办法识别用户的原籍国,然后通过将他们的国家 Iso-2-Letter-Code
附加到 URL 来修改请求 URL,然后使用新 URL 重定向用户。如果请求URL有国家代码,那么应该绕过这个请求修改。
我更喜欢使用或创建 asp.net 核心中间件的解决方案,我可以在 Startup.cs 中将其附加到我的 HTTP 请求管道,或者涉及将新自定义路由添加到默认 MVC 的解决方案路线。
非常感谢您的帮助和想法。
.Net有个现成的功能,可以知道是什么来头。它被称为Culture Info。
默认情况下,每个客户端都会传递一个文化信息,或者他们可以指定他们打算使用的当前 language/country 是什么。
我的建议是允许客户在 Header 名称调用 "Accept-Language" 中指定 culture-info。例如,我在美国并且打算使用英语,我会在 header.
中发送 'en-us' 作为我请求的一部分
在后端服务器内部,我会检查这个 header 并适当地设置 culture-info。
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;
}
}
我正在尝试根据用户正在查看我的应用程序的国家/地区对发送回用户的内容进行本地化,这意味着他们的国家/地区代码应该是请求的一部分 url。例如,如果用户在美国,所有请求 URL 应该是 http://website.com/us/{controller}/{action}.
话虽如此,有没有办法识别用户的原籍国,然后通过将他们的国家 Iso-2-Letter-Code
附加到 URL 来修改请求 URL,然后使用新 URL 重定向用户。如果请求URL有国家代码,那么应该绕过这个请求修改。
我更喜欢使用或创建 asp.net 核心中间件的解决方案,我可以在 Startup.cs 中将其附加到我的 HTTP 请求管道,或者涉及将新自定义路由添加到默认 MVC 的解决方案路线。
非常感谢您的帮助和想法。
.Net有个现成的功能,可以知道是什么来头。它被称为Culture Info。
默认情况下,每个客户端都会传递一个文化信息,或者他们可以指定他们打算使用的当前 language/country 是什么。
我的建议是允许客户在 Header 名称调用 "Accept-Language" 中指定 culture-info。例如,我在美国并且打算使用英语,我会在 header.
中发送 'en-us' 作为我请求的一部分在后端服务器内部,我会检查这个 header 并适当地设置 culture-info。
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;
}
}