繁体   English   中英

在MVC基本控制器上覆盖设置文化的最合适方法

[英]Most suitable method to override on mvc base controller for setting culture

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

考虑性能,哪一个最适合这份工作? (以上4种方法只是示例,有关完整列表,请参见MSDN

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

我们发现,Initialize方法是设置此设置的最佳位置,因为在其他方法之前以及在任何操作过滤器之前都会调用它。 这对我们很重要,因为我们希望动作过滤器能够兑现预期的文化。

我不确定在每种方法中设置区域性是否会有性能差异。 我相信它们只会在不同的时间点执行,即在动作过滤器之前,模型绑定之前和tempdata加载之后等。

我相信我们在源存储库中的某个地方有一个帮助器类,它将概述我们的工作方式。 让我知道您是否愿意,我会对其进行调查。

对不起,我知道您的问题是针对性能的,我只是想分享自己的经验。

更新

根据要求,这里是我们使用的帮助程序类。

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;

    }

}

要使用它,只需重写控制器的Initialize方法

protected override void Initialize(RequestContext requestContext)
{

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

    base.Initialize(requestContext);
}

这种方法的好处是,在用户不知情的情况下,首次根据用户的浏览器设置自动设置区域性。

它也可以退回到主要语言,因此,如果用户请求en-US,但应用程序仅支持en-GB,则返回en-GB仍然很聪明,因为它仍然是英语。

有任何问题请告诉我:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM