Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在mvc基本控制器上重写以设置区域性的最合适方法_C#_Asp.net Mvc_Globalization - Fatal编程技术网

C# 在mvc基本控制器上重写以设置区域性的最合适方法

C# 在mvc基本控制器上重写以设置区域性的最合适方法,c#,asp.net-mvc,globalization,C#,Asp.net Mvc,Globalization,我的mvc应用程序中有一个基本控制器,所有控制器都从中继承。基本控制器继承System.Web.Mvc命名空间中的抽象类控制器,我需要在每个控制器操作上设置区域性。我可以覆盖许多方法,比如OnActionExecuting、Initialize、ExecuteCore、BeginExecute 考虑到工作表现,哪一个最适合这份工作?(以上4种方法只是综合列表的示例,请参见)我们实现了一种基于用户的Accept Language标头更改区域性的方法,但也允许他们自己明确设置,我们问了自己同样的问题

我的mvc应用程序中有一个基本控制器,所有控制器都从中继承。基本控制器继承
System.Web.Mvc
命名空间中的抽象类控制器,我需要在每个控制器操作上设置区域性。我可以覆盖许多方法,比如
OnActionExecuting、Initialize、ExecuteCore、BeginExecute


考虑到工作表现,哪一个最适合这份工作?(以上4种方法只是综合列表的示例,请参见)

我们实现了一种基于用户的Accept Language标头更改区域性的方法,但也允许他们自己明确设置,我们问了自己同样的问题

我们发现Initialize方法是设置它的最佳位置,因为它在其他方法和任何操作过滤器之前被调用。这对我们来说很重要,因为我们希望行动过滤器尊重预期的文化

我不确定在每种方法中设置文化是否会有任何性能差异。我相信它们只会在不同的时间点执行,即在操作过滤器之前、modelbinding之前和tempdata加载之后等

我相信我们在源repo上有一个helper类,它将概述我们是如何做到这一点的。如果你想要这个,请告诉我,我会把它挖出来

抱歉,我知道你的问题更注重性能,我只是想分享我的经验

更新

根据要求,这里是我们使用的helper类

public class GlobalisationCookie
{

    public GlobalisationCookie(HttpRequestBase request, HttpResponseBase response)
    {
        _request = request;
        _response = response;

    }

    private readonly HttpRequestBase _request;
    private readonly HttpResponseBase _response;

    //
    // Gets a collection of users languages from the Accept-Language header in their request
    //
    private String[] UserLanguges
    {
        get
        {
            return _request.UserLanguages;
        }

    }

    //
    // A dictionary of cultures the application supports - We point this to a custom webconfig section
    //  This collection is in order of priority
    public readonly Dictionary<string, string> SupportedCultures = new Dictionary<string, string>() { { "en-GB", "English - British" }, { "no", "Norwegian"} }

    //
    //  Summary:
    //       reads the first part of the culture i.e "en", "es"
    //
    private string GetNeutralCulture(string name)
    {
        if (!name.Contains("-")) return name;

        return name.Split('-')[0];
    }



    //
    //  Summary:
    //      returns the validated culture code or default
    //
    private string ValidateCulture(string userCulture)
    {

        if (string.IsNullOrEmpty(userCulture))
        {
            //no culture found - return default
            return SupportedCultures.FirstOrDefault().Key;
        }

        if (SupportedCultures.Keys.Any(x => x.Equals(userCulture, StringComparison.InvariantCultureIgnoreCase)))
        {
            //culture is supported by the application!
            return userCulture;
        }

        //  find closest match based on the main language. for example
        //      if the user request en-GB return en-US as it is still an English language
        var mainLanguage = GetNeutralCulture(userCulture);

        foreach (var lang in SupportedCultures)
        {
            if (lang.Key.StartsWith(mainLanguage)) return lang.Key;
        }

        return SupportedCultures.FirstOrDefault().Key;

    }


    //
    // Called from the OnInitialise method. Sets the culture based on the users cookie or accepted language
    //
    public void CheckGlobalCookie()
    {

        string cultureCode;

        var cookie = _request.Cookies["Globalisation"];

        if (cookie != null)
        {
            cultureCode = cookie.Value;
        }
        else
        {
            cultureCode = UserLanguges != null ? UserLanguges[0] : null;
        }

        //
        // Check we support this culture in our application
        //
        var culture = ValidateCulture(cultureCode);

        //
        // Set the current threads culture
        //
        Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(culture);
        Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

    }

    //
    //  Summary
    //      Called when the user picks there own culture
    //
    public void SetGlobalisationCookie(string culture)
    {

        culture = ValidateCulture(culture);

        var cookie = _request.Cookies["Globalisation"];

        if (cookie != null)
        {

            cookie.Value = culture;
        }
        else
        {

            cookie = new HttpCookie("Globalisation")
            {
                Value = culture,
                Expires = DateTime.Now.AddYears(1)
            };

        }

        cookie.Domain = FormsAuthentication.CookieDomain;
        _response.Cookies.Add(cookie);

        Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(culture);
        Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

    }

}
这种方法的好处是,用户第一次进入应用程序时,将根据其浏览器设置自动设置区域性,而用户不知道

它还可以回退到主语言,因此如果用户请求en-US,但应用程序只支持en-GB,那么它很聪明,可以返回en-GB,因为它仍然是一种英语


如果您有任何问题,请告诉我:)

应用程序中的不同控制器是否需要不同的区域性?否,但用户的区域性设置可以通过在应用程序中设置首选项来更改,完成此操作后,整个应用程序必须遵守新的区域性设置。感谢您的见解。我很想看看你的应用程序是如何做到这一点的。谢谢你在这里发布你的解决方案,它看起来很不错,我想知道在哪里放置文化更改代码和cookie解决方案也很好,也许我会使用整个东西连同url参数,如果选择了语言(标记),将传递url参数
protected override void Initialize(RequestContext requestContext)
{

    new GlobalisationCookie(requestContext.HttpContext.Request, requestContext.HttpContext.Response).CheckGlobalCookie();

    base.Initialize(requestContext);
}