从当前访问者那里获取CultureInfo并根据它设置资源?

Mat*_*zen 29 asp.net-mvc

我如何(在ASP .NET MVC中)获取当前访问者的CultureInfo(基于他/她的浏览器语言)?

我不知道从哪里开始.我试着查看浏览器发送的"Accept-Languages"标题.但这是最好的方式吗?

Ser*_*sev 55

Request.UserLanguages是您正在寻找的房产.请记住,此数组可能包含由请求标头设置的任意(甚至非exsitent)语言.

UPDATE

例:

// Get Browser languages.
var userLanguages = Request.UserLanguages;
CultureInfo ci;
if (userLanguages.Count() > 0)
{
    try
    {
        ci = new CultureInfo(userLanguages[0]);
    }
    catch(CultureNotFoundException)
    {
         ci = CultureInfo.InvariantCulture;
    }
}
else
{
    ci = CultureInfo.InvariantCulture;
}
// Here CultureInfo should already be set to either user's prefereable language
// or to InvariantCulture if user transmitted invalid culture ID
Run Code Online (Sandbox Code Playgroud)

  • 引用:`通常这些由语言的双字符代码,连字符和文化的双字符代码组成,例如美国英语的"en-us"和加拿大法语的"fr-ca". .所以它是一个包含这些值的`string []`数组. (4认同)
  • 这些语言标记的一般形式在RFC 5646(http://tools.ietf.org/html/rfc5646)中指定.如果你假设"ab-CD",当有人指定字母表(sd-Arab-PK)时你会被抛出. (2认同)

Tin*_*ren 10

Asp.Net Core 版本:使用RequestLocalization即从 HTTP 请求中检索文化。

在 Startup.cs - 配置

app.UseRequestLocalization();
Run Code Online (Sandbox Code Playgroud)

然后在你的 Controller/Razor Page.cs

var locale = Request.HttpContext.Features.Get<IRequestCultureFeature>();
var BrowserCulture = locale.RequestCulture.UICulture.ToString();
Run Code Online (Sandbox Code Playgroud)

  • 这是一个更好的答案。 (2认同)

Chr*_*ris 7

您可以使用类似于以下内容的代码来获取用户的各种详细信息(包括语言):

MembershipUser user = Membership.GetUser(model.UserName);
string browser = HttpContext.Request.Browser.Browser;
string version = HttpContext.Request.Browser.Version;
string type = HttpContext.Request.Browser.Type;
string platform = HttpContext.Request.Browser.Platform;
string userAgent = HttpContext.Request.UserAgent;
string[] userLang = HttpContext.Request.UserLanguages
Run Code Online (Sandbox Code Playgroud)


Cor*_*y-G 6

它似乎Request.UserLanguages在更高的 mvc 版本中不可用(Asp.net core mvc 2.0.2 没有它。)

我做了一个扩展方法进行HTTPRequest。使用方法如下:

var requestedLanguages = Request.GetAcceptLanguageCultures();
Run Code Online (Sandbox Code Playgroud)

该方法将按Accept-Language偏好顺序(又名“质量”)为您提供来自标题的文化。

public static class HttpRequestExtensions
{
    public static IList<CultureInfo> GetAcceptLanguageCultures(this HttpRequest request)
    {
        var requestedLanguages = request.Headers["Accept-Language"];
        if (StringValues.IsNullOrEmpty(requestedLanguages) || requestedLanguages.Count == 0)
        {
            return null;
        }

        var preferredCultures = requestedLanguages.ToString().Split(',')
            // Parse the header values
            .Select(s => new StringSegment(s))
            .Select(StringWithQualityHeaderValue.Parse)
            // Ignore the "any language" rule
            .Where(sv => sv.Value != "*")
            // Remove duplicate rules with a lower value
            .GroupBy(sv => sv.Value).Select(svg => svg.OrderByDescending(sv => sv.Quality.GetValueOrDefault(1)).First())
            // Sort by preference level
            .OrderByDescending(sv => sv.Quality.GetValueOrDefault(1))
            .Select(sv => new CultureInfo(sv.Value.ToString()))
            .ToList();

        return preferredCultures;
    }
}
Run Code Online (Sandbox Code Playgroud)

测试过 ASP.NET Core MVC 2.0.2

它类似于@mare 的答案,但更新了一点,并且不会忽略 q(质量)。此外,您可能希望将 附加CultureInfo.InvariantCulture到列表的末尾,具体取决于您的使用情况。


mar*_*are 5

我正在为一个明星标记这个问题并在这里分享一些代码,这些代码基本上变成了Request.UserLanguagesCultureInfo实例的数组,以便在您的应用程序中进一步使用.使用CultureInfo比使用ISO代码更灵活,因为使用CultureInfo可以访问文化的所有属性(如名称,两个字符的语言名称,本机名称......):

        // Create array of CultureInfo objects
        string locale = string.Empty;
        CultureInfo[] cultures = new CultureInfo[Request.UserLanguages.Length + 1];
        for (int ctr = Request.UserLanguages.GetLowerBound(0); ctr <= Request.UserLanguages.GetUpperBound(0);
                 ctr++)
        {
            locale = Request.UserLanguages[ctr];
            if (!string.IsNullOrEmpty(locale))
            {

                // Remove quality specifier, if present.
                if (locale.Contains(";"))
                    locale = locale.Substring(0, locale.IndexOf(';'));
                try
                {
                    cultures[ctr] = new CultureInfo(locale, false);
                }
                catch (Exception) { continue; }
            }
            else
            {
                cultures[ctr] = CultureInfo.CurrentCulture;
            }
        }
        cultures[Request.UserLanguages.Length] = CultureInfo.InvariantCulture;
Run Code Online (Sandbox Code Playgroud)

HTH