[转载]ASP.NET MVC2.0本地化(另类解决方案)

[转载]MVC2.0本地化(另类解决方案) – RyanDing – 博客园.

前不久看见一篇文章:在ASP.NET中使用Response.Filter 过滤网站敏感字符的解决方案。于是我借题发挥用Response.Filter 为MVC2.0 进行多国语言本地化。如果存在不足的地方,希望您指出。

本文主要给出具体思路,希望能给读者带来一定的启发:日常开发中不是所有的方案要中规中矩用常用方法解决问题。比如本文的本地化就不用resource文件来处理。

具体步骤:

一、建立自定义的LocalizationHandler类


LocalizationHandler 继承System.IO.Stream类 ,LocalizationHandler实例化后赋值给Response.Filter。这里主要通过Response.Filter来本地化MVC2.0程序。具体的Response.Filter 用法请参看MSDN.代码如下:

001 public class LocalizationHandler : Stream
002 {
003
004 private Stream responseStream;
005
006
007 public LocalizationHandler(Stream inputStream)
008 {
009 responseStream = inputStream;
010 }
011
012 public override bool CanRead
013 {
014 get { return true; }
015 }
016
017 public override bool CanSeek
018 {
019 get { return true; }
020 }
021
022 public override bool CanWrite
023 {
024 get { return true; }
025 }
026
027 public override void Flush()
028 {
029 responseStream.Flush();
030 }
031
032 public override long Length
033 {
034 get { return 0; }
035 }
036
037 long postion;
038 public override long Position
039 {
040 get
041 {
042 return postion;
043 }
044 set
045 {
046 postion = value;
047 }
048 }
049
050 public override int Read(byte[] buffer, int offset, int count)
051 {
052 return responseStream.Read(buffer, offset, count);
053 }
054
055 public override long Seek(long offset, SeekOrigin origin)
056 {
057 return responseStream.Seek(offset, origin);
058 }
059
060 public override void SetLength(long value)
061 {
062 responseStream.SetLength(value);
063 }
064
065 public override void Write(byte[] buffer, int offset, int count)
066 {
067 string sBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
068 string pattern = @"(<|<)=(.*?)(>|>)";//正则替换类似页面格式为这样的字符串如:<=OtherContent>
069 sBuffer = Regex.Replace(sBuffer, pattern, delegate(Match c)
070 {
071 return ReadLocalizationResource().FirstOrDefault(d => d.Key == c.Groups[2].Value).Value;
072 });
073
074 ReadLocalizationResource();
075 byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(sBuffer);
076 responseStream.Write(data, 0, data.Length);
077 }
078
079 ObjectCache cache = MemoryCache.Default;
080 private Dictionary<string, string> ReadLocalizationResource()
081 {
082 string _XMLPath = "";
083
084 Dictionary<string, string> cacheData = null;
085 if (cacheData != null)
086 {
087 return cacheData;
088 }
089 Dictionary<string, string> cachedData = new Dictionary<string, string>();
090
091 string serverPath = System.Web.HttpContext.Current.Server.MapPath("~");
092 _XMLPath = Path.Combine(serverPath, "LocalizationResource.xml");
093
094 //建立缓存(使用.net4.0最新缓存机制:System.Runtime.Caching;)
095 if (cache["myCache"] == null)
096 {
097 CacheItemPolicy policy = new CacheItemPolicy();
098 policy.SlidingExpiration = TimeSpan.FromMinutes(60);
099 policy.ChangeMonitors.Add(new HostFileChangeMonitor(new List<string> { _XMLPath }));
100
101 var items = XElement.Load(_XMLPath).Elements("Module").Elements("item");
102 foreach (var item in items)
103 {
104 string key = item.Attribute("name").Value;
105 string value = item.Value;
106 cachedData.Add(key, value);
107 }
108 cache.Set("myCache", cachedData, policy);
109
110 return cachedData;
111
112 }
113
114 return (Dictionary<string, string>)cache["myCache"];
115 }
116 }

代码中的65行开始,是本地化核心代码,在这里我们用正则匹配文本。用.NET4.0 System.Runtime.Caching;(尝鲜)缓存机制提高程序执行效率。

二、修改global.asax文件


在global.asax中加入以下代码:

1 protected void Application_BeginRequest(Object sender, EventArgs e)
2 {
3 Response.Filter = new LocalizationHandler(Response.Filter);
4 }

三、建立自定义的XML本地化资源文件


截图如下:

OK,一切准备就绪,我们在不用Response.Filter 过滤的情况下,运行截图如下:

使用上文中Response.Filter过滤后:

结果将第三点中的XML作为传统的资源文件后本地化了MVC View 页面。

四、小结


本文用另外一套方案解决了MVC2.0程序的本地化问题,也适用于ASP.NET webform。同时本文还存在很多不足的地方,比如后台异步的JSON格式本地化、用户自定义本地化语言等将会在MVC2.0本地化(另类解决方 案)<下> 文中得到完善。

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏