【问题标题】:Detecting browser display language检测浏览器显示语言
【发布时间】:2013-09-16 10:56:24
【问题描述】:

通过使用以下代码

string[] languages = HttpContext.Current.Request.UserLanguages;
string chosenLanguage = languages[0];

如果我安装了 3 种语言(例如“da(丹麦语)”、“sv(瑞典语)”和“en(英语)”),那么语言数组如下所示:

[0]: "en-US"
[1]: "en;q=0.8"
[2]: "da;q=0.6"
[3]: "sv;q=0.4"

即使我将显示语言更改为“丹麦语”而不是“英语”,该数组也不会更改任何值。据我从其他人写的关于这个主题的文章中可以看出,[0] 值应该是浏览器选择的语言,但它仍然是"en-US"

还有其他方法可以注册浏览器的语言还是我做错了什么?

【问题讨论】:

标签: c# asp.net


【解决方案1】:

在 page 指令上设置 UICultureCulture 对我有用:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" UICulture="auto" Culture="auto" %>

然后我将我的 chrome 语言设置为 French 并确保重新排序语言 - chrome 会将最上面的语言作为浏览器的默认语言

然后我用了:

Response.Write(System.Threading.Thread.CurrentThread.CurrentUICulture);

哪个正确给了我fr

您可以在页面级别或全局设置文化,see here

【讨论】:

  • 成功了!太棒了,谢谢。我想知道为什么 chrome 会采用最顶层的语言而不是当前的显示语言,但我想这就是它的制作方式。我在其他浏览器中再次测试,效果很好。
  • 很高兴听到,乐于助人!
  • support.google.com/chromebook/answer/1059490 Chrome 文档,用于将最常用的语言作为网站的默认语言。谷歌对用户非常不友好。您会认为,当您选择重新加载浏览器或检查默认设置时,它会将其移至您的顶部。
【解决方案2】:

我有一个 MVC 应用程序,必须以不同的方式处理这个问题。我们的应用程序使用 url 参数化语言。我可以推荐,因为接受的答案无法更改为另一种语言。它还可以被不同语言的搜索引擎抓取,并允许用户保存或发送具有特定语言的 URL。

但是,在最初的请求中,我想检测用户语言,现在 OP 提到它无法更改顺序,这是因为某些浏览器(Chrome)正在确定这一点,而不管您设置的语言如何。 如您所见,我将界面语言设置为英语,但为了测试,我将德语移至仅用于翻译的顶部,结果:

因此,Chrome 只是将用户在设置中设置的任何内容放在首位。大多数用户可能只会将他们的用户界面语言设置为他们想要用于翻译/拼写检查的一些语言。 所以这是我的代码

Global.asax

protected void Session_Start(Object sender, EventArgs e)
{
    Session["sessionId"] = Session.SessionID;
    Session.Timeout = 120;
    //first point of request, get the user's browser language
    string[] languages = Request.UserLanguages;
    if (languages != null && Session.IsNewSession)
    {
        LanguageEnum requestLanguage = LanguageHelper.GetLanguage(languages);
        if (requestLanguage != LanguageEnum.NL)//NL is default for the sources
        {
            Response.RedirectToRoute("Locolized", new { lang = requestLanguage.ToString().ToLower() });//Locolized is an route name, see below
        }
    }
}

语言助手

public static LanguageEnum GetLanguage(string[] languages)
{
    if (languages == null) return DefaultLanguage;
    LanguageEnum lang = DefaultLanguage;
    bool firstDone = false;
    foreach (string language in languages)
    {
        string realLanguage = Regex.Replace(language, "[;q=(0-9).]", "");
        LanguageEnum givenlang = GetLanguage(realLanguage);//converts it to an enum, overload method.
        //first one should be the used language that is set for a browser (if user did not change it their self).
        //In some browsers their might be multiple languages (for translations)
        if (!firstDone)
        {
            firstDone = true;
            lang = givenlang; 
        }
        else
        {
            //ranking others
            lang = RankLanguage(lang, givenlang);
        }

    }
    return lang;
}

private static LanguageEnum RankLanguage(LanguageEnum existing, LanguageEnum newLnag)
{
    if (existing == LanguageEnum.EN && newLnag != LanguageEnum.EN)
    {
        //everything that is other then english gets a higher rank
        return newLnag;
    }
    //add other usecases here specific to your application/use case, keep in mind that all other languages could pass
    return existing;
}

//below code is for setting the language culture I use, 
//fixed number and date format for now, this can be improved.
//might be if your interests if you want to use parameterized languages

    public static void SetLanguage(LanguageEnum language)
    {
        string lang = "";
        switch (language)
        {
            case LanguageEnum.NL:
                lang = "nl-NL";
                break;
            case LanguageEnum.EN:
                lang = "en-GB";
                break;
            case LanguageEnum.DE:
                lang = "de-DE";
                break;
        }
        try
        {
            NumberFormatInfo numberInfo = CultureInfo.CreateSpecificCulture("nl-NL").NumberFormat;
            CultureInfo info = new CultureInfo(lang);
            info.NumberFormat = numberInfo;
            //later, we will if-else the language here
            info.DateTimeFormat.DateSeparator = "/";
            info.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
            Thread.CurrentThread.CurrentUICulture = info;
            Thread.CurrentThread.CurrentCulture = info;
        }
        catch (Exception)
        {

        }
    }

您可能对我处理参数化网址的方式感兴趣:

RouteConfig.cs 在其他映射下方

routes.MapRoute(
    name: "Locolized",
    url: "{lang}/{controller}/{action}/{id}",
    constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})" },   // en or en-US
    defaults: new { controller = "shop", action = "index", id = UrlParameter.Optional }
);

FilterConfig.cs(可能需要添加,如果需要,在Global.asax中的Application_start()方法中添加FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new ErrorHandler.AiHandleErrorAttribute());
        //filters.Add(new HandleErrorAttribute());
        filters.Add(new LocalizationAttribute("nl-NL"), 0);
    }
}

最后,LocalizationAttribute

public class LocalizationAttribute : ActionFilterAttribute
{
    private string _DefaultLanguage = "nl-NL";
    private string[] allowedLanguages = { "nl", "en" };

    public LocalizationAttribute(string defaultLanguage)
    {
        _DefaultLanguage = defaultLanguage;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string lang = (string) filterContext.RouteData.Values["lang"] ?? _DefaultLanguage;
        LanguageHelper.SetLanguage(lang);
    }
}

剩下要做的就是添加资源,这是我之前写的一个回答:https://stackoverflow.com/a/35813707/2901207

【讨论】:

    【解决方案3】:

    你试过Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")吗??

    这是我的输出fr-FR,en-US;q=0.5

    【讨论】:

    • HttpRequest.UserLanguages 从中获取它的价值,所以它不会有什么不同。
    • 我得到的回复是"en-US,en;q=0.8,da;q=0.6,sv;q=0.4",不幸的是,这几乎是一样的。
    • 在我的情况下,当我在 IE 中向上移动法语时 .. Request.ServerVariables["HTTP_ACCEPT_LANGUAGE"] 确实先显示“fr”,然后在 Request.ServerVariables["HTTP_ACCEPT_LANGUAGE"] 中显示“en”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-11
    • 2011-10-30
    • 2011-04-15
    • 2019-02-17
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多