Обнаружение языка отображения браузера

Используя следующий код

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

Есть ли другой способ зарегистрировать язык браузера, или я делаю что-то неправильно?

Ответ 1

Настройка UICulture и Culture в директиве страницы работала для меня:

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

Затем я установил свой хром-язык на French и обязательно переупорядочил языки - chrome будет использовать самый верхний язык по умолчанию для браузера.

Затем я использовал:

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

Что правильно дал мне fr

Вы можете установить культуру на уровне страницы или глобально, см. здесь.

Ответ 2

Вы пробовали Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")??

вот мой вывод fr-FR,en-US;q=0.5

Ответ 3

У меня есть приложение MVC, и мне пришлось иметь дело с этим по-другому. Наше приложение использует языки с параметрами URL. Что я могу порекомендовать, потому что переход на другой язык невозможен для принятого ответа. Он также стал сканироваться поисковыми системами на разных языках и позволяет пользователю сохранять или отправлять URL-адрес с определенным языком.

Но по первоначальному запросу я хотел бы определить язык пользователя, теперь OP упомянул, что он не может изменить порядок, то есть потому, что некоторые браузеры (Chrome) определяют это, независимо от установленного вами языка. выбор языка хрома Как вы видите, у меня есть язык интерфейса, установленный на английском языке, но для проверки я переместил немецкий язык на верх, который я использую только для перевода, результат:

languages ​​

Таким образом, 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 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);
    }
}

Что нужно сделать, это добавить ресурсы, вот более ранний ответ, который я написал, который охватывает: fooobar.com/info/109079/...