ASP.NET MVC用IHttpModule修改response的html实现压缩或者转繁体,IHttpModule用后台代码注册

46 篇文章 1 订阅
25 篇文章 0 订阅

代码里面实现了html里面中文简体转繁体,用的微软自带的简繁体类库操作,效率高。在FilterStream中,Write方法里面还可以实现压缩html

实现IhttpModule操作模块

using System;
using System.Web;

namespace OverrideRender.Models
{
    public class MyHttpModule : IHttpModule
    {
        void IHttpModule.Dispose()
        {
            //throw new NotImplementedException();
        }

        void IHttpModule.Init(HttpApplication context)
        {
            context.BeginRequest += Context_BeginRequest;
        }

        private void Context_BeginRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Response.Filter = new FilterStream(HttpContext.Current.Response.Filter);
        }
    }
}
注册MyHttpModule,此方式注册不需要在Global.asax中注册即可生效,此类在程序注册所有Modules模块前注册到模块集合中,所以能生效
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using System.Web;

[assembly: PreApplicationStartMethod(typeof(OverrideRender.Models.PreApplicationStartRegist), "PreStart")]
namespace OverrideRender.Models
{
    public class PreApplicationStartRegist
    {
        private static bool hasLoaded;
        public static void PreStart()
        {
            if (!hasLoaded)
            {
                hasLoaded = true;
                //动态注册操作模块
                DynamicModuleUtility.RegisterModule(typeof(MyHttpModule));
            }
        }
    }
}

继承Stream,改写类,使能操作html,改写html关键类

    public class FilterStream : Stream
    {
        private Stream _sm;
        public FilterStream(Stream stream)
        {
            _sm = stream;
        }
        public override bool CanRead
        {
            get
            {
                return true;
            }
        }

        public override bool CanSeek
        {
            get
            {
                return true;
            }
        }

        public override bool CanWrite
        {
            get
            {
                return true;
            }
        }

        public override long Length
        {
            get
            {
                return _sm.Length;
            }
        }

        public override long Position
        {
            get
            {
                return _sm.Position;
            }

            set
            {
                _sm.Position = value;
            }
        }

        public override void Flush()
        {
            _sm.Flush();
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return _sm.Read(buffer, offset, count);
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return _sm.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            _sm.SetLength(value);
        }

        //不用轉換的類型列表
        static List<string> checkTypes = new List<string>() { "jpeg", "gif", "png", "bmp", "pdf", "xlsx", "doc", "xls" };

        /// <summary>
        /// 获取到响应输出流的html文本,并修改html
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        public override void Write(byte[] buffer, int offset, int count)
        {
            //檢查文件類型
            string fileType = CheckFileType.CheckTrueFileName(buffer);
            if (!checkTypes.Contains(fileType))
            {
                //取得返回到浏览器的html
                string html = Encoding.UTF8.GetString(buffer);
                //将html里面的简体中文转换为繁体,末尾參數設置為1033為了防止頁面亂碼產生
                string tHtml = Microsoft.VisualBasic.Strings.StrConv(html, VbStrConv.TraditionalChinese, 1033);              
                //覆盖原html,载入修改后的html   
                byte[] buff = Encoding.UTF8.GetBytes(tHtml);
                _sm.Write(buff, 0, buff.Length);
            }
            else
            {
                _sm.Write(buffer, 0, buffer.Length);
            }
        }
    }

检查文件真实类型

    public class CheckFileType
    {
        /// <summary>
        /// 檢測文件真實類型
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string CheckTrueFileName(byte[] bytes)
        {
            //16進制字符
            string hexStr = " ";
            try
            {
                byte[] headBytes = bytes.Take(4).ToArray();
                hexStr = ByteTo16HexStr(headBytes);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
            }
            //真实的文件类型
            string fileName = "";
            FileTypeDictionary.TryGetValue(hexStr, out fileName);
            //Console.WriteLine(fileName);
            return fileName;
        }
        /// <summary>
        /// 將字節數組轉換為16進制字符串
        /// </summary>
        /// <param name="inputStr">傳入字節數組</param>
        /// <param name="encoding">16進制字符串</param>
        /// <returns></returns>
        public static string ByteTo16HexStr(byte[] buffer)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte item in buffer)
            {
                sb.AppendFormat("{0:X2}", item);
            }
            return sb.ToString();
        }
        /// <summary>
        /// 字節數組頭對應的文件類型
        /// </summary>
        public static Dictionary<string, string> FileTypeDictionary
        {
            get
            {
                Dictionary<string, string> dict = new Dictionary<string, string>();
                dict.Add("FFD8FFE0", "jpeg");
                dict.Add("89504E47", "png");
                dict.Add("47494638", "gif");
                dict.Add("424D424F", "bmp");
                dict.Add("504B0304", "zip/xlsx/docx");
                dict.Add("52617221", "rar");
                dict.Add("D0CF11E0", "xls/doc");
                dict.Add("25504446", "pdf");
                dict.Add("2F2A210D", "js");
                dict.Add("3C3F786D", "xml");
                dict.Add("7B0D0A20", "json");
                return dict;
            }
        }
    }
1028 繁體中文
1033 ASCII
2052 簡體中文
為何第二次轉換回繁體時,不用 1028 而用 1033 呢?
首先,要先知道,有些簡體中文的編碼值是在繁體中文是對應不到任何字的。此時,顯示的字就會是 "?" 號。
因為 2052 的 「 国] 已經是簡體字了,轉回到繁體時,剛好其編碼對應不到1028 的編碼,因此會是問號。
处理简体转换为繁体,页面出现乱码问题,参考地址:
https://www.cnblogs.com/fmxyw/archive/2010/02/26/1674447.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王焜棟琦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值