2015-06-24 1 views
2

У меня есть базовый контроллер в моем приложении mvc, от которого наследуются все контроллеры. базовый контроллер наследует абстрактный класс Controller в пространстве имен System.Web.Mvc, мне нужно установить культуру для каждого действия контроллера. Есть много методов, которые я могу переопределить, как OnActionExecuting, Initialize, ExecuteCore, BeginExecuteНаиболее подходящий метод для переопределения на базовом контроллере mvc для настройки культуры

Принимая во внимание, какой из них лучше всего подходит для работы? (приведенные выше 4 метода являются лишь примерами для полного списка, см. MSDN)

+0

Вам нужны разные культуры для разных контроллеров в приложении? –

+0

Нет, но настройку культуры пользователя можно изменить, установив предпочтения в приложении, когда это будет сделано, все приложение должно соблюдать новую настройку культуры. – Ahsan

ответ

3

Мы внедрили способ изменения культуры на основе заголовка Accept-Language пользователя, но также позволили им объяснить это сами, и мы спросили себя одинаково вопрос.

Мы нашли метод Initialize лучшим местом для его установки, поскольку он вызывается перед другими методами и перед любыми фильтрами действий. Это было важно для нас, поскольку мы хотели, чтобы фильтры действий соблюдали намеченную культуру.

Я не уверен, будет ли какая-либо разница в производительности, определяющая культуру в каждом из этих методов. Я считаю, что они просто выполнили бы в разные моменты времени, а затем до фильтров действий, прежде чем моделировать & после загрузки tempdata и т. Д.

Я считаю, что у нас есть вспомогательный класс где-то на нашем исходном репо, в котором мы расскажем, как мы это сделали. Дайте мне знать, если вы этого захотите, и я выкопаю его.

Извинения, я знаю, что ваш вопрос был более специфичным для производительности. Я просто хотел поделиться своим опытом.

Update

В соответствии с просьбой вот вспомогательный класс мы использовали.

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; 

    } 

} 

Чтобы использовать его, просто переопределить метод инициализации контроллера

protected override void Initialize(RequestContext requestContext) 
{ 

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

    base.Initialize(requestContext); 
} 

Хорошая вещь об этом подходе является культура будет автоматически устанавливается в первый раз, когда пользователь вводит приложение на основе настроек браузера без знания пользователем.

Он также может отступить на основной язык, поэтому, если пользователь запрашивает en-US, но приложение поддерживает только en-GB, оно достаточно умно для возврата en-GB, поскольку оно по-прежнему является английским.

Дайте мне знать, если у вас есть вопросы :)

+0

Спасибо за понимание. хотелось бы видеть, как это делается в вашем приложении. – Ahsan

+0

@Ahsan Нашли код - я обновил свой ответ. – heymega

+0

Спасибо, что разместили свое решение здесь, это выглядит красиво, мне было интересно, куда положить код изменения культуры и решение cookie тоже приятно, может быть, я собираюсь использовать все это вместе с параметром url, который будет передан, если язык выбран (тег) –

Смежные вопросы