利用 Generic Handler 把 Global Resource 動態轉成物件給 JavaScript 使用,結果如下:
上篇,我們了解如何使用本地與全域資源,現在我也想要讓 JavaScript 也能套用資源檔,馬上來看怎麼做
@JavaScriptGlobalResourceHandler.ashx
ResourceManager+GetResourceSet 用來列舉資源檔定義,主要是把資源檔轉成 Dictionary<object,object>
private Dictionary<object, object> ReadResources( string resourceKey, string requestedUICulture) { var uiCultureInfo = CultureInfo.GetCultureInfo(requestedUICulture); var resourceManager = this.CreateResourceManager(resourceKey); var resourceSet = resourceManager.GetResourceSet(uiCultureInfo, true, true); Dictionary<object, object> result = null; result = resourceSet.Cast<DictionaryEntry>().ToDictionary( x => x.Key, x => resourceManager.GetObject((string)x.Key, uiCultureInfo)); return result; }
將 ResourceManager 放在一個 Pool 裡面,需要用的時候再拿取來
private ResourceManager CreateResourceManager(string resourceKey) { //var assembly = s_globalAssembly; var key = "Resources." + resourceKey; ResourceManager resourceManager = null; if (s_resourceManagerPool.ContainsKey(key)) { resourceManager = s_resourceManagerPool[key]; } else { resourceManager = new ResourceManager(key, s_globalAssembly); s_resourceManagerPool.Add(key, resourceManager); } return resourceManager; }
再將 Dictionary<object,object> 換成 JavaScript 的物件
private string GenerateJavaScriptObject(string requestResourceKey, Dictionary<object, object> globalResources) { var javaScriptSerializer = new JavaScriptSerializer(); var script = @" if (typeof(Resources) == ""undefined"") Resources = {}; Resources." + requestResourceKey + " = " + javaScriptSerializer.Serialize(globalResources) + ";"; return script; }
最後我用 Generic Handler 裝載,Cache一天,並寫到 Client端
public void ProcessRequest(HttpContext context) { var requestedUICulture = context.Request.QueryString["UICulture"]; var requestResourceKey = context.Request.QueryString["ResourceKey"]; if (string.IsNullOrWhiteSpace(requestedUICulture)) { throw new ArgumentNullException("UICulture"); } if (string.IsNullOrWhiteSpace(requestResourceKey)) { throw new ArgumentNullException("ResourceKey"); } var globalResources = this.ReadResources(requestResourceKey, requestedUICulture); var javaScriptObject = this.GenerateJavaScriptObject(requestResourceKey, globalResources); context.Response.ContentType = "application/javascript"; context.Response.Expires = 1440;//1天 context.Response.Cache.SetLastModified(DateTime.UtcNow); context.Response.Write(javaScriptObject); }
完整程式碼:
@Default.aspx
javascript 參考 JavaScriptGlobalResourceHandler
<%@ Import Namespace="System.Globalization" %> ... <head runat="server"> <title></title> <script type="text/javascript" src="JavaScriptGlobalResourceHandler.ashx?ResourceKey=SystemConfig&UICulture=<%= CultureInfo.CurrentUICulture %>"></script> </head>
在 javaScript 就能使用 Resources.SystemConfig.Love,這就跟我們在使用 Global 的後端資源一樣
<script type="text/javascript"> function clicked(sender, args) { var msg = Resources.SystemConfig.Love; alert(msg); } </script>
完整程式碼:
切換語系
利用 Cookie 存放 Culture 狀態
@Global.asax
protected void Application_BeginRequest(object sender, EventArgs e) { var language = Utility.GetLanguage(); CultureInfo currentInfo = CultureInfo.GetCultureInfo(language); Thread.CurrentThread.CurrentCulture = currentInfo; Thread.CurrentThread.CurrentUICulture = currentInfo; }
完整程式碼:
@Default.aspx.cs
protected void English_Button_Click(object sender, EventArgs e) { Utility.WriteLanguage("en-US"); this.Response.Redirect(this.Request.RawUrl); } protected void Chinese_Button_Click(object sender, EventArgs e) { Utility.WriteLanguage("zh-TW"); this.Response.Redirect(this.Request.RawUrl); }
@Utility.cs
預設拿瀏覽器的 HttpContext.Current.Request.UserLanguages 語系,cookie 若有狀態,則替換
public static string GetLanguage() { string language = HttpContext.Current.Request.UserLanguages[0]; var cookie = HttpContext.Current.Request.Cookies[LANGUAGE]; if (cookie != null) { language = cookie.Value; } return language; } public static void WriteLanguage(string culture) { var cookie = HttpContext.Current.Request.Cookies[LANGUAGE]; if (cookie == null) { cookie = new HttpCookie(LANGUAGE); } cookie.HttpOnly = true; cookie.Expires = DateTime.Now.AddDays(1); cookie.Value = culture; HttpContext.Current.Response.Cookies.Add(cookie); }
執行結果
利用 Generic Handler 把 Global Resource 動態轉成物件給 JavaScript 使用,結果如下:
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET