C# 检测浏览器显示语言

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18826282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:20:47  来源:igfitidea点击:

Detecting browser display language

c#asp.net

提问by Loyalar

By using the following code

通过使用以下代码

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

if I have installed 3 languages (ex. "da (danish)", "sv (swedish)" and "en (english)"), then the languages array looks like this:

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

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

Even if I change the display language to "Danish" instead of "English" then the array doesn't change any of the values. As far as I can read from what other people have written about this subject, the [0]value should be the chosen language of the browser, but it is still "en-US".

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

Is there some other way to register the language of the browser or am I doing something wrong?

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

采纳答案by DGibbs

Setting the UICultureand Cultureon the page directive worked for me:

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

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

I then set my chrome language to Frenchand made sure to re-order the languages - chrome will take the topmost language as default for the browser.

然后我将我的 chrome 语言设置为French并确保重新排序语言 - chrome 将采用最顶层的语言作为浏览器的默认语言

I then used:

然后我使用了:

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

Which correctly gave me fr

哪个正确地给了我 fr

You can set the culture on the page level or globally, see here.

您可以在页面级别或全局设置文化,请参阅此处

回答by Dhaval

Have you tried Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")??

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

here is my output fr-FR,en-US;q=0.5

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

回答by CularBytes

I have an MVC application and had to deal with this in a different way. Our application is using url parameterized languages. Which I can recommend because changing to another language is not possible for the accepted answer. It also became crawlable by search engines in different languages and allows the user to save or send a URL with a specific lang.

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

But, on initial request I would like to detect the user language, now the OP mentioned it could not change the order, that is because some browsers (Chrome) are determining this, regardless of the language you have set. chrome language selectionAs you can see I have the interface language set to English, but to test I moved German to the top which I only use for translation, result:

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

languages

语言

So Chrome just puts on top whatever the user has set in the settings. Most users will probably only have set their user interface language their and some languages they want to use for translations/spellchecks. So here is my code

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

Global.asax

全球.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
        }
    }
}

Language Helper

语言助手

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)
        {

        }
    }

The way I handle parameterized urls might be of your interest:

我处理参数化 url 的方式可能会引起您的兴趣:

RouteConfig.csBelow the other mappings

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(might need to be added, if so, add FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);to the Application_start()method in Global.asax

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

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

And finally, the LocalizationAttribute

最后,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);
    }
}

What is left to do is add Resources, here is an earlier answer I wrote that covers that: https://stackoverflow.com/a/35813707/2901207

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