ASP.NET MVC实现Localize站点的 Action Filter
假设你已经了解Action Filter(see ASP.NET MVC的官方Understanding Action Filters),下面实现了Localize的Filter,直接看代码:
1 using System.Globalization; 2 using System.Web.Mvc; 3 4 namespace LocalizedMVC.Controllers 5 { 6 public class SetCultureAttribute : FilterAttribute, IActionFilter 7 { 8 #region Enums 9 10 /// <summary> 11 /// Represents the location the culture code can be found 12 /// </summary> 13 public enum CultureLocation 14 { 15 /// <summary> 16 /// This option should never be used. 17 /// </summary> 18 None = 0, 19 /// <summary> 20 /// Use when the culture code is saved in a cookie. 21 /// When using be sure to specify the CookieName property. 22 /// </summary> 23 Cookie = 1, 24 /// <summary> 25 /// Use when the culture code is specified in the query string. 26 /// When using be sure to specify the QueryStringParamName property. 27 /// </summary> 28 QueryString = 2, 29 /// <summary> 30 /// Use when the culture code is saved in session state. 31 /// When using be sure to specify the SessionParamName property. 32 /// </summary> 33 Session = 4, 34 /// <summary> 35 /// Use when the culture code is specified in the URL. 36 /// This assume a format of "{language}/{country}". 37 /// When using be sure to specify the CountryActionParamName and 38 /// LanguageActionParamName properties. 39 /// </summary> 40 URL = 16 41 } 42 43 #endregion Enums 44 45 #region Properties 46 47 /// <summary> 48 /// The name of the cookie containing the culture code. Specify this value when CultureStore is set to Cookie. 49 /// </summary> 50 public string CookieName { get; set; } 51 /// <summary> 52 /// The name of the action parameter containing the country code. Specify this value when CultureStore is set to URL. 53 /// </summary> 54 public string CountryActionParamName { get; set; } 55 /// <summary> 56 /// The CultureLocation where the culture code is to be read from. This is required to be set. 57 /// </summary> 58 public CultureLocation CultureStore { get; set; } 59 /// <summary> 60 /// The name of the action parameter containing the language code. Specify this value when CultureStore is set to URL. 61 /// </summary> 62 public string LanguageActionParamName { get; set; } 63 /// <summary> 64 /// The name of the query string parameter containing the country code. Specify this value when CultureStore is set to QueryString. 65 /// </summary> 66 public string QueryStringParamName { get; set; } 67 /// <summary> 68 /// The name of the session parameter containing the country code. Specify this value when CultureStore is set to Session. 69 /// </summary> 70 public string SessionParamName { get; set; } 71 72 #endregion Properties 73 74 #region IActionFilter implementation 75 76 public void OnActionExecuted(ActionExecutedContext filterContext) 77 { 78 79 } 80 81 public void OnActionExecuting(ActionExecutingContext filterContext) 82 { 83 if (CultureStore == CultureLocation.None) 84 return; 85 86 string cultureCode = GetCultureCode(filterContext); 87 88 //now that we've collected the culture code, set the culture for the thread 89 if (!string.IsNullOrEmpty(cultureCode)) 90 { 91 try 92 { 93 CultureInfo culture = new CultureInfo(cultureCode); 94 System.Threading.Thread.CurrentThread.CurrentCulture = culture; 95 System.Threading.Thread.CurrentThread.CurrentUICulture = culture; 96 } 97 catch 98 { 99 //TODO: Handle error? Really, what can we do besides log it? 100 } 101 } 102 } 103 104 #endregion IActionFilter implementation 105 106 protected string GetCultureCode(ActionExecutingContext filterContext) 107 { 108 //Everything but CultureLocation.URL requires a valid HttpContext 109 if (CultureStore != CultureLocation.URL) 110 { 111 if (filterContext.RequestContext.HttpContext == null) 112 return string.Empty; 113 } 114 115 string cultureCode = string.Empty; 116 117 if (CultureStore == CultureLocation.Cookie) 118 { 119 if (filterContext.RequestContext.HttpContext.Request.Cookies[CookieName] != null 120 && filterContext.RequestContext.HttpContext.Request.Cookies[CookieName].Value != string.Empty) 121 { 122 cultureCode = filterContext.RequestContext.HttpContext.Request.Cookies[CookieName].Value; 123 } 124 125 return cultureCode; 126 } 127 128 if (CultureStore == CultureLocation.QueryString) 129 { 130 cultureCode = filterContext.RequestContext.HttpContext.Request[QueryStringParamName]; 131 return cultureCode ?? string.Empty; 132 } 133 134 if (CultureStore == CultureLocation.Session) 135 { 136 if (filterContext.RequestContext.HttpContext.Session[SessionParamName] != null 137 && filterContext.RequestContext.HttpContext.Session[SessionParamName].ToString() != string.Empty) 138 { 139 cultureCode = filterContext.RequestContext.HttpContext.Session[SessionParamName].ToString(); 140 } 141 142 return cultureCode; 143 } 144 145 //if URL it is expected the URL path will contain the culture 146 if (CultureStore == CultureLocation.URL) 147 { 148 if (filterContext.ActionParameters[LanguageActionParamName] != null && filterContext.ActionParameters[CountryActionParamName] != null 149 && filterContext.ActionParameters[LanguageActionParamName].ToString() != string.Empty && filterContext.ActionParameters[CountryActionParamName].ToString() != string.Empty 150 ) 151 { 152 string language = filterContext.ActionParameters[LanguageActionParamName].ToString(); 153 string country = filterContext.ActionParameters[CountryActionParamName].ToString(); 154 cultureCode = language + "-" + country; 155 } 156 157 return cultureCode; 158 } 159 160 return cultureCode ?? string.Empty; 161 } 162 } 163 }
如何使用呢?
[HandleError]
[SetCulture(CultureStore = SetCultureAttribute.CultureLocation.QueryString, QueryStringParamName = "culture")]
public class HomeController : Controller
{ ... actions ... }
QueryString 的方式:
http://localhost/?culture=en-GB"
如果存在session中你可以修改属性为那些东东为:
[SetCulture(CultureStore = SetCultureAttribute.CultureLocation.Session, SessionParamName = "culture")]
如果存在cookie中你可以修改属性为:
[SetCulture(CultureStore = SetCultureAttribute.CultureLocation.Cookie, CookieName = "culture")]
如果想通用URL标准你期待的国家和语言时,那可能你的route需要认同.当请求http://localhost/en/us/home/about" 这个URL时...看下面的代码,
routes.MapRoute(
"Default", // Route name
"{language}/{country}/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "", language = "en", country = "US" } // Parameter defaults
);
更新路由后,修改SetCulture的属性为:
[SetCulture(CultureStore = SetCultureAttribute.CultureLocation.URL, CountryActionParamName = "country", LanguageActionParamName = "language")]
等等....
culture代码在当前的线程与UI通过这种方式设置:
CultureInfo culture = new CultureInfo (cultureCode);
System.Threading.Thread.CurrentThread.CurrentCulture = culture;
System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
作者:PetterLiu blog: http://wintersun.cnblogs.com 参考:source