![](/img/trans.png)
[英]calling base.OnCallStateChanged on overriding gets a no suitable method found to override
[英]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.