zoukankan      html  css  js  c++  java
  • Asp.net使用HttpResponse.Filter 实现简繁/繁简转换

    HttpResponse.Filter 属性,类似于 HttpRequest.Filter,只不过一个是出口,一个是入口(想像一下停车场),在这两个点之间的数据由服务器端处理,在这两点之外的,则由用户浏览器处理。那么,在出口处能做些什么呢?当然是对数据进行一些统一的处理,比如说简繁转换、过滤非法词汇等等。

    在这里说说如何做简繁转换,其实网上已经有很多例子,所以只是针对一些重点的部分说明一下:

    首先,依然是实现自己的过滤器,需要继承 Stream:

    public class ResponseFilter : Stream

    在重写基类方法时,最重要的是 Write() 方法,所有的转换都在该方法中实现,主要代码如下:

    1. public override void Write(byte[] buffer, int offset, int count)
    2. {
    3. //判断 Session,若 Session["Lang"] 等于 "ZH-TW",则启动转换
    4. if (HttpContext.Current.Session != null && HttpContext.Current.Session["Lang"].ToString() == "ZH-TW")
    5. {
    6. //对于 UTF-8 编码,必须提供简繁字对照,为提高处理效率,应删除简繁体写法相同的字,这样至少可以减少 2/3 的字数(网上提供的字库大多包含了相同字符的)
    7. //GB 转 Big5 可使用 Microsoft.VisualBasic.Strings.StrConv 方法,不需要字库。
    8. String simple = "简体字库";
    9. String tradit = "繁體字庫";
    10. //获取当前响应流的编码方式,即使整个网站都使用 UTF-8 编码,但仍然会存在其它的编码方式,尤其是采用微软的 Ajax 控件时,若编码方式不一致,则会导致错误,动态获取编码,可避免这个问题
    11. System.Text.Encoding curEncoding = HttpContext.Current.Response.ContentEncoding;
    12. string strBuff = curEncoding.GetString(buffer);
    13. int len = strBuff.Length;
    14. System.Text.StringBuilder sbBuff = new System.Text.StringBuilder();
    15. for (int i = 0; i != len; ++i)
    16. {
    17. int index = simple.IndexOf(strBuff[i]);
    18. if (index != -1)
    19. sbBuff.Append(tradit[index]);
    20. else
    21. sbBuff.Append(strBuff[i]);
    22. }
    23. byte[] output = System.Text.Encoding.UTF8.GetBytes(sbBuff.ToString());
    24. m_sink.Write(output, 0, count);
    25. }
    26. else
    27. m_sink.Write(buffer, 0, count);
    28. }

    写好自己的过滤器后,就可以加载到网站中了,注意,跟 HttpRequest.Filter 一样,HttpResponse.Filter 的加载也是在 Global.asax 的 Application_BeginRequest 事件中,另外,因为在该事件触发时,Session 尚未启动,所以不能在此使用Session 判定当前的语言,代码如下:

    1. void Application_BeginRequest(object sender, EventArgs e)
    2. {
    3. string rawUrl = Request.RawUrl.ToLower();
    4. // rawUrl.IndexOf(".axd")用於屏蔽 Asp.net Ajax 生成的异步请求。否则部分使用 Ajax 的页面会报错,原因不明。
    5. if (rawUrl.IndexOf(".axd") == -1)
    6. {
    7. this.Response.Charset = "UTF-8";
    8. this.Response.Buffer = false;
    9. this.Response.Filter = new ResponseFilter(Response.Filter);
    10. }
    11. }

    至此,一个简单的网站简繁转换就完成了,但在实际应用中,出现过这样一种情况,有时在访问网站时,会提示

    工作阶段状态已经建立工作阶段 ID,但由于应用程序已经清除回应而无法储存。

    出现的频率不高,并且无规律,即使当前未进行转换也会出现,并且只出现在页面下方,也不像通常的错误显示一样,仅出现错误信息,而是错误信息和本来的页面都显示出来。

    后来在一份文档中看到说是使用 Response.Flush、Response.Write 等导致输出缓冲区刷新的语句,有时会造成 Session 丢失(因为网站另外使用了一些 Session 来储存一些状态值),所以在 Global.asax 的创建 Session 事件中,重建网站需要的状态 Session 值:

    1. void Session_Start(object sender, EventArgs e)
    2. {
    3. //判断 Session 是否丢失
    4. if (!String.IsNullOrEmpty(Session.SessionID))
    5. {
    6. //网站状态 Session 设为默认值(这里不用管用于判断是简体还是繁体那个 Session)
    7. … …
    8. }
    9. }

    问题解决。

    有可能还会有这种需求,要将一些带有简体字的图片也转换为繁体,怎么办呢?呵呵,其实很简单,对需要转换的图片名称后加一个特殊的字串,比如简体的 图片名为 "image__zh__.gif“,相应的繁体图片为 "image__tw__.gif",将 __zh__ 替换为 __tw__就可以了。

  • 相关阅读:
    ansible register 之用法
    vim 多行注释和取消注释
    开启 ssh 的 root 登录
    HAproxy 添加多个配置文件
    1002. A+B for Polynomials (25)
    Java中浮点数能连续精确表示整数的范围
    1001. A+B Format (20)
    1003. 我要通过!(20)
    1009. 说反话 (20)
    1006. 换个格式输出整数 (15)
  • 原文地址:https://www.cnblogs.com/luoyaoquan/p/2027357.html
Copyright © 2011-2022 走看看