C# 如何在asp.net mvc中正确检测用户浏览器文化

C# 如何在asp.net mvc中正确检测用户浏览器文化,c#,asp.net,asp.net-mvc,asp.net-mvc-4,uiculture,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 4,Uiculture,我看到有类似的问题,但我还没有找到我的问题的答案,因此,我决定问我自己的问题 情况:我想获取用户的浏览器语言,这样我就可以设置他的会话区域性密钥,或者如果用户有帐户,则可以将本地化存储在数据库中,以便在该用户手动更改语言首选项之前,用他的语言向该用户显示我的网站 我的问题是:理论上一切似乎都很好,但 这些是我的浏览器语言首选项 我知道它们是按特定顺序排列的 无论我的浏览器显示语言是否设置为保加利亚语,该命令都会发送到服务器。我的首选项仍然保留在美国 这是一个示例代码片段,用于显示我的开发工具

我看到有类似的问题,但我还没有找到我的问题的答案,因此,我决定问我自己的问题

情况:我想获取用户的浏览器语言,这样我就可以设置他的会话区域性密钥,或者如果用户有帐户,则可以将本地化存储在数据库中,以便在该用户手动更改语言首选项之前,用他的语言向该用户显示我的网站

我的问题是:理论上一切似乎都很好,但

这些是我的浏览器语言首选项 我知道它们是按特定顺序排列的

无论我的浏览器显示语言是否设置为保加利亚语,该命令都会发送到服务器。我的首选项仍然保留在美国

这是一个示例代码片段,用于显示我的开发工具控制台对我的浏览器显示语言的说明

在我的代码中,我不知道什么是浏览器语言,我只能向用户获取首选语言,然后获取语言[0]

有没有办法获得这种显示语言。我无法使用JS发送它,因为我有一个问题,我的第一个请求总是以英语显示页面,而不是在设置会话时显示本地化页面。可能有一种解决方法可以检查和设置JS中的特定头,但我正在考虑一种更大胆的方法,只使用C#

我不确定这是正确的方法。我已经在BaseController中重写了OnActionExecuting,我正在根据用户的区域设置设置当前线程的本地化,他可能会通过下拉其首选语言来更改,该语言也会重写并重置会话语言键。我也知道有一个自动区域设置选项,但我不确定它是否足够好,而且我也不知道它是如何工作的,以及用户如何在自动全球化打开时简单地更改其语言


目前,我只想获得适当的浏览器显示语言,我需要处理本地化问题的人员的帮助。

您可以使用CultureHelper:

public static class CultureHelper
{

// Valid cultures
    private static readonly List<string> _validCultures = new List<string> {         "af", "af-ZA", "sq", "sq-AL", "gsw-FR", "am-ET", "ar", "ar-DZ", "ar-BH", "ar-   EG", "ar-IQ", "ar-JO", "ar-KW", "ar-LB", "ar-LY", "ar-MA", "ar-OM", "ar-QA", "ar-SA", "ar-SY", "ar-TN", "ar-AE", "ar-YE", "hy", "hy-AM", "as-IN", "az", "az-Cyrl-AZ", "az-Latn-AZ", "ba-RU", "eu", "eu-ES", "be", "be-BY", "bn-BD", "bn-IN", "bs-Cyrl-BA", "bs-Latn-BA", "br-FR", "bg", "bg-BG", "ca", "ca-ES", "zh-HK", "zh-MO", "zh-CN", "zh-Hans", "zh-SG", "zh-TW", "zh-Hant", "co-FR", "hr", "hr-HR", "hr-BA", "cs", "cs-CZ", "da", "da-DK", "prs-AF", "div", "div-MV", "nl", "nl-BE", "nl-NL", "en", "en-AU", "en-BZ", "en-CA", "en-029", "en-IN", "en-IE", "en-JM", "en-MY", "en-NZ", "en-PH", "en-SG", "en-ZA", "en-TT", "en-GB", "en-US", "en-ZW", "et", "et-EE", "fo", "fo-FO", "fil-PH", "fi", "fi-FI", "fr", "fr-BE", "fr-CA", "fr-FR", "fr-LU", "fr-MC", "fr-CH", "fy-NL", "gl", "gl-ES", "ka", "ka-GE", "de", "de-AT", "de-DE", "de-LI", "de-LU", "de-CH", "el", "el-GR", "kl-GL", "gu", "gu-IN", "ha-Latn-NG", "he", "he-IL", "hi", "hi-IN", "hu", "hu-HU", "is", "is-IS", "ig-NG", "id", "id-ID", "iu-Latn-CA", "iu-Cans-CA", "ga-IE", "xh-ZA", "zu-ZA", "it", "it-IT", "it-CH", "ja", "ja-JP", "kn", "kn-IN", "kk", "kk-KZ", "km-KH", "qut-GT", "rw-RW", "sw", "sw-KE", "kok", "kok-IN", "ko", "ko-KR", "ky", "ky-KG", "lo-LA", "lv", "lv-LV", "lt", "lt-LT", "wee-DE", "lb-LU", "mk", "mk-MK", "ms", "ms-BN", "ms-MY", "ml-IN", "mt-MT", "mi-NZ", "arn-CL", "mr", "mr-IN", "moh-CA", "mn", "mn-MN", "mn-Mong-CN", "ne-NP", "no", "nb-NO", "nn-NO", "oc-FR", "or-IN", "ps-AF", "fa", "fa-IR", "pl", "pl-PL", "pt", "pt-BR", "pt-PT", "pa", "pa-IN", "quz-BO", "quz-EC", "quz-PE", "ro", "ro-RO", "rm-CH", "ru", "ru-RU", "smn-FI", "smj-NO", "smj-SE", "se-FI", "se-NO", "se-SE", "sms-FI", "sma-NO", "sma-SE", "sa", "sa-IN", "sr", "sr-Cyrl-BA", "sr-Cyrl-SP", "sr-Latn-BA", "sr-Latn-SP", "nso-ZA", "tn-ZA", "si-LK", "sk", "sk-SK", "sl", "sl-SI", "es", "es-AR", "es-BO", "es-CL", "es-CO", "es-CR", "es-DO", "es-EC", "es-SV", "es-GT", "es-HN", "es-MX", "es-NI", "es-PA", "es-PY", "es-PE", "es-PR", "es-ES", "es-US", "es-UY", "es-VE", "sv", "sv-FI", "sv-SE", "syr", "syr-SY", "tg-Cyrl-TJ", "tzm-Latn-DZ", "ta", "ta-IN", "tt", "tt-RU", "te", "te-IN", "th", "th-TH", "bo-CN", "tr", "tr-TR", "tk-TM", "ug-CN", "uk", "uk-UA", "wen-DE", "ur", "ur-PK", "uz", "uz-Cyrl-    UZ", "uz-Latn-UZ", "vi", "vi-VN", "cy-GB", "wo-SN", "sah-RU", "ii-CN", "yo-NG"    };
    // Include ONLY cultures you are implementing
    private static readonly List<string> _cultures = new List<string> {
    "fr",// first culture is the DEFAULT
    "ar",  
    "en"

    };
    /// <summary>
    /// Returns true if the language is a right-to-left language. Otherwise, false.
    /// </summary>
    public static bool IsRighToLeft()
    {
        return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.IsRightToLeft;

    }
    /// <summary>
    /// Returns a valid culture name based on "name" parameter. If "name" is not valid, it returns the default culture "en-US"
    /// </summary>
    /// <param name="name" />Culture's name (e.g. en-US)</param>
    public static string GetImplementedCulture(string name)
    {
        // make sure it's not null
        if (string.IsNullOrEmpty(name))
            return GetDefaultCulture(); // return Default culture
        // make sure it is a valid culture first
        if (_validCultures.Where(c => c.Equals(name, StringComparison.InvariantCultureIgnoreCase)).Count() == 0)
            return GetDefaultCulture(); // return Default culture if it is invalid
        // if it is implemented, accept it
        if (_cultures.Where(c => c.Equals(name, StringComparison.InvariantCultureIgnoreCase)).Count() > 0)
            return name; // accept it
        // Find a close match. For example, if you have "en-US" defined and the user requests "en-GB", 
        // the function will return closes match that is "en-US" because at least the language is the same (ie English)  
        var n = GetNeutralCulture(name);
        foreach (var c in _cultures)
            if (c.StartsWith(n))
                return c;
        // else 
        // It is not implemented
        return GetDefaultCulture(); // return Default culture as no match found
    }
    /// <summary>
    /// Returns default culture name which is the first name decalared (e.g. en-US)
    /// </summary>
    /// <returns></returns>
    public static string GetDefaultCulture()
    {
        return _cultures[0]; // return Default culture
    }
    public static List<string> GetCultures()
    {
        return _cultures;
    }
    public static string GetCurrentCulture()
    {
        return Thread.CurrentThread.CurrentCulture.Name;
    }
    public static string GetCurrentNeutralCulture()
    {
        return GetNeutralCulture(Thread.CurrentThread.CurrentCulture.Name);
    }
    public static string GetNeutralCulture(string name)
    {
        if (!name.Contains("-")) return name;

        return name.Split('-')[0]; // Read first part only. E.g. "en", "es"
    }
}
公共静态类CultureHelper
{
//有效文化
私有静态只读列表有效文化=新列表{“af”、“af ZA”、“sq”、“sq AL”、“gsw FR”、“am ET”、“ar”、“ar DZ”、“ar BH”、“ar-EG”、“ar IQ”、“ar JO”、“ar KW”、“ar LB”、“ar LY”、“ar MA”、“ar OM”、“ar QA”、“ar SA”、“ar SY”、“ar TN”、“ar AE”、“ar YE”、“hy am”、“as IN”、“az”、“az Cyrl az”、“az Latn”、“BARU”、“eu”、“eu ES”,“be”、“be BY”、“bn BD”、“bn IN”、“bs Cyrl BA”、“bs Latn BA”、“br FR”、“bg”、“bg bg”、“ca”、“ca ES”、“zh HK”、“zh MO”、“zh CN”、“zh Hans”、“zh SG”、“zh TW”、“zh Hant”、“co FR”、“hr”、“hr BA”、“cs”、“cs CZ”、“da”、“da DK”、“prs AF”、“div”、“div MV”、“nl”、“nl be”、“nl nl nl nl”、“en”、“en”、“en AU”、“en BZ”、“en ca”、“en-029”、“en-IN”、“en-IE”、“en-JM”“,”en MY“,”en NZ“,”en PH“,”en SG“,”en ZA“,”en TT“,”en GB“,”en US“,”en ZW“,”et EE“,”fo“,”fo-fo“,”fil-PH“,”fi-fi“,”fr-fi“,”fr-LU“,”fr-MC“,”fr-CH“,”fy-NL“,”gl-NL“,”gl“,”ka“,”ka“,”de“,”de“,”de-AT“,”de-de“,”de-LI“,”de-LU,“he-IL”、“hi”、“hi-IN”、“hu”、“hu-hu”、“is”、“is”、“ig-NG”、“id”、“iu-Latn-CA”、“iu-Cans-CA”、“ga-IE”、“xh-ZA”、“zu-ZA”、“it”、“it-it”、“it-CH”、“ja-JP”、“kn”、“kn-IN”、“kk”、“kk-kk”、“rw”、“sw-KE”、“ko-kk”、“ko”、“ky”、“KG”、“KG”、“lo-LA”、“lv”、“lv”、“lv-lv-lv”、“lt”、“lt-lt”、“wee-DE”、“lb-LU”“,”mk“,”mk“,”mk“,”ms“,”ms BN“,”ms MY“,”mt mt“,”mt NZ“,”arn CL“,”mr IN“,”moh CA“,”mn“,”mn mn mn“,”mn Mong CN“,”ne NP“,”no“,”nb no“,”nn no“,”oc FR“,”或IN“,”ps AF“,”fa“,”fa“,”fa IR“,”pl“,”pt BR“,”pt pt pt pt pt pt pt pt pt pt pt pt pt pt pt pt pt pt pt pt“,”pa“,”pa“,“smj SE”、“SE FI”、“SE NO”、“SE SE”、“sms FI”、“sma NO”、“sma SE”、“sa”、“sa IN”、“sr”、“sr Cyrl BA”、“sr Cyrl SP”、“sr Latn BA”、“sr Latn SP”、“nso ZA”、“tn ZA”、“si LK”、“sk”、“sk sk”、“sl”、“sl si”、“es”、“es AR”、“es BO”、“es CL”、“es CO”、“es CR”、“es DO”、“es EC”、“es SV”、“es GT”、“es HN”、“es MX”、“es NI”、“es PA”、“es PA”、“es PE”,“es PR”、“es es es”、“es US”、“es UY”、“es VE”、“sv”、“sv FI”、“sv SE”、“syr”、“syr SY”、“tg Cyrl TJ”、“tzm Latn DZ”、“ta”、“ta IN”、“tt”、“tt RU”、“te IN”、“th”、“th”、“th”、“bo CN”、“tr”、“tr”、“tk TM”、“ug CN”、“uk UA”、“wen DE”、“ur PK”、“uz”、“uz Cyrl-uz”、“uz Latn uz”、“vi”、“vi VN”、“vi VN”、“cy GB”、“wo SN”、“sah RU”、“ii CN”、“ii CN”等”yo NG“};
//仅包括您正在实施的文化
私有静态只读列表_cultures=新列表{
“fr”//默认为第一个区域性
“ar”,
“嗯”
};
/// 
///如果语言是从右向左的语言,则返回true。否则返回false。
/// 
公共静态bool IsRighToLeft()
{
返回System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.IsRightToLeft;
}
/// 
///基于“name”参数返回有效的区域性名称。如果“name”无效,则返回默认区域性“en US”
/// 
///文化名称(例如en US)
公共静态字符串GetImplementedCulture(字符串名称)
{
//确保它不是空的
if(string.IsNullOrEmpty(name))
return GetDefaultCulture();//返回默认区域性
//首先确保它是一个有效的区域性
if(_validCultures.Where(c=>c.Equals(name,StringComparison.InvariantCultureIgnoreCase)).Count()==0)
return GetDefaultCulture();//如果默认区域性无效,则返回默认区域性
//如果实现了,就接受它
if(_cultures.Where(c=>c.Equals(name,StringComparison.InvariantCultureIgnoreCase)).Count()>0)
返回name;//接受它
//查找相近的匹配项。例如,如果您定义了“en US”,并且用户请求“en GB”,
  <script>
  var currentLang = '@CultureHelper.GetCurrentCulture()';
 </script>