19

通过使用以下代码

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".

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

4

3 回答 3

23

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

<%@ 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

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

于 2013-09-16T11:21:45.013 回答
8

我有一个 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
        }
    }
}

语言助手

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

        }
    }

我处理参数化 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 }
);

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

最后,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

于 2017-06-19T13:47:49.683 回答
3

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

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

于 2013-09-16T11:14:23.233 回答