检测浏览器显示语言

Loy*_*lar 18 c# asp.net

通过使用以下代码

string[] languages = HttpContext.Current.Request.UserLanguages;
string chosenLanguage = languages[0];
Run Code Online (Sandbox Code Playgroud)

如果我安装了3种语言(例如"da(danish)","sv(swedish)"和"en(english)"),那么语言数组如下所示:

[0]: "en-US"
[1]: "en;q=0.8"
[2]: "da;q=0.6"
[3]: "sv;q=0.4"
Run Code Online (Sandbox Code Playgroud)

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

有没有其他方式来注册浏览器的语言或我做错了什么?

DGi*_*bbs 18

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

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" UICulture="auto" Culture="auto" %>
Run Code Online (Sandbox Code Playgroud)

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

然后我用了:

Response.Write(System.Threading.Thread.CurrentThread.CurrentUICulture);
Run Code Online (Sandbox Code Playgroud)

这正确地给了我 fr

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


Cul*_*tes 7

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

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

语言

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

全球.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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

语言助手

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

        }
    }
Run Code Online (Sandbox Code Playgroud)

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

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 }
);
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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