RyanDing

用编码抒写未来

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  41 随笔 :: 0 文章 :: 1243 评论 :: 52万 阅读

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

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

    具体步骤:

    一、建立自定义的LocalizationHandler类


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
public class LocalizationHandler : Stream
   {
 
       private Stream responseStream;
 
 
       public LocalizationHandler(Stream inputStream)
       {
           responseStream = inputStream;
       }
 
       public override bool CanRead
       {
           get { return true; }
       }
 
       public override bool CanSeek
       {
           get { return true; }
       }
 
       public override bool CanWrite
       {
           get { return true; }
       }
 
       public override void Flush()
       {
           responseStream.Flush();
       }
 
       public override long Length
       {
           get { return 0; }
       }
 
       long postion;
       public override long Position
       {
           get
           {
               return postion;
           }
           set
           {
               postion = value;
           }
       }
 
       public override int Read(byte[] buffer, int offset, int count)
       {
           return responseStream.Read(buffer, offset, count);
       }
 
       public override long Seek(long offset, SeekOrigin origin)
       {
           return responseStream.Seek(offset, origin);
       }
 
       public override void SetLength(long value)
       {
           responseStream.SetLength(value);
       }
 
       public override void Write(byte[] buffer, int offset, int count)
       {
           string sBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
           string pattern = @"(<|<)=(.*?)(>|>)";//正则替换类似页面格式为这样的字符串如:<=OtherContent>
           sBuffer = Regex.Replace(sBuffer, pattern, delegate(Match c)
           {
               return ReadLocalizationResource().FirstOrDefault(d => d.Key == c.Groups[2].Value).Value;
           });
 
           ReadLocalizationResource();
           byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(sBuffer);
           responseStream.Write(data, 0, data.Length);
       }
 
       ObjectCache cache = MemoryCache.Default;
       private Dictionary<string, string> ReadLocalizationResource()
       {
           string _XMLPath = "";
 
           Dictionary<string, string> cacheData = null;
           if (cacheData != null)
           {
               return cacheData;
           }
           Dictionary<string, string> cachedData = new Dictionary<string, string>();
 
           string serverPath = System.Web.HttpContext.Current.Server.MapPath("~");
           _XMLPath = Path.Combine(serverPath, "LocalizationResource.xml");
 
           //建立缓存(使用.net4.0最新缓存机制:System.Runtime.Caching;)
           if (cache["myCache"] == null)
           {
               CacheItemPolicy policy = new CacheItemPolicy();
               policy.SlidingExpiration = TimeSpan.FromMinutes(60);
               policy.ChangeMonitors.Add(new HostFileChangeMonitor(new List<string> { _XMLPath }));
 
               var items = XElement.Load(_XMLPath).Elements("Module").Elements("item");
               foreach (var item in items)
               {
                   string key = item.Attribute("name").Value;
                   string value = item.Value;
                   cachedData.Add(key, value);
               }
               cache.Set("myCache", cachedData, policy);
 
               return cachedData;
 
           }
 
           return (Dictionary<string, string>)cache["myCache"];
       }
   }

 

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

 

   二、修改global.asax文件


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

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

 

 

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


截图如下:

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

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

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

 

   四、小结


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

 

希望本篇文章可以给您带来帮助,如有不足之处欢迎指出,谢谢!

posted on   ryanding  阅读(3218)  评论(28编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
点击右上角即可分享
微信分享提示