zoukankan      html  css  js  c++  java
  • Asp.Net MVC页面静态化功能实现一:利用IHttpModule,摒弃ResultFilter

    上一篇有提到利用IHttpModule和ResultFilter实现页面静态化功能。后来经过一些改动,将ResultFilter中要实现的功能全部转移到IHttpModule中来实现

    Asp.Net MVC页面静态化功能实现一:利用IHttpModule和ResultFilter

    1、改动后的自定义IHttpModule实现代码:

    public class RouterHttpModule : IHttpModule
    {
        public void Init(HttpApplication application)
        {
            application.BeginRequest += this.Application_BeginRequest; //注册事件
        }
    
        private void Application_BeginRequest(Object source, EventArgs e)
        {
            HttpApplication application = (HttpApplication)source;
            HttpContext context = application.Context;
            string filePath = context.Request.FilePath;
            string fileExtension = VirtualPathUtility.GetExtension(filePath);
            //如果当前请求的不是资源文件、不是后台管理、请求中没有表单信息、静态页面存在,则返回静态页面
            if (string.IsNullOrEmpty(fileExtension) && !filePath.ToLower().StartsWith("/admin") && context.Request.Form.Count.Equals(0))
            {
                string htmlPath = context.Request.HtmlFilePath();
                if (File.Exists(htmlPath))
                {
                    context.Response.WriteFile(htmlPath);
                    context.Response.End();
                }
                context.Response.Filter = new HttpResponseFilterWrapper(context.Response.Filter, context);
            }
        }
    
        public void Dispose() { }
    }

    这里只是在判断静态页面文件是否存在之后加了这样一段代码:context.Response.Filter = new HttpResponseFilterWrapper(context.Response.Filter, context);

    2、HttpResponseFilterWrapper的实现代码

    HttpResponseFilterWrapper的功能还跟以前一样,保存Filter中返回给客户端的html代码到服务器硬盘上

    public class HttpResponseFilterWrapper : Stream
    {
        private Stream inner;
        private HttpContext context;
        public HttpResponseFilterWrapper(System.IO.Stream s, HttpContext context)
        {
            this.inner = s;
            this.context = context;
        }
    
        public override bool CanRead
        {
            get { return inner.CanRead; }
        }
    
        public override bool CanSeek
        {
            get { return inner.CanSeek; }
        }
    
        public override bool CanWrite
        {
            get { return inner.CanWrite; }
        }
    
        public override void Flush()
        {
            inner.Flush();
        }
    
        public override long Length
        {
            get { return inner.Length; }
        }
    
        public override long Position
        {
            get{ return inner.Position; }
            set{ inner.Position = value; }
        }
    
        public override int Read(byte[] buffer, int offset, int count)
        {
            return inner.Read(buffer, offset, count);
        }
    
        public override long Seek(long offset, System.IO.SeekOrigin origin)
        {
            return inner.Seek(offset, origin);
        }
    
        public override void SetLength(long value)
        {
            inner.SetLength(value);
        }
    
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (!context.Response.StatusCode.Equals(200))
            {
                return;
            }
            inner.Write(buffer, offset, count);
            //if (!context.HttpContext.Request.FilePath.ToLower().StartsWith("/admin"))
            //当前请求不是后台管理;并且返回客户端是html才生成静态页面
            if (!context.Request.FilePath.ToLower().StartsWith("/admin") && context.Response.ContentType.Equals("text/html"))
            {
                //静态页面保存路径信息
                string htmlPath = context.Request.HtmlFilePath();
                string direcHtmlPath = Path.GetDirectoryName(htmlPath);  
                if (!Directory.Exists(direcHtmlPath))
                {
                    Directory.CreateDirectory(direcHtmlPath);
                }
                //获取返回客户端的html代码,并进行压缩处理
                string htmlCode = System.Text.Encoding.UTF8.GetString(buffer); 
                string isZipHtml = WebConfigInfo.GetConfigValueByKey("IsCompressed");
                //如果“IsCompressed”的值为空或0,则表示不压缩
                if (!string.IsNullOrEmpty(isZipHtml) && !isZipHtml.Equals(0))
                {
                    htmlCode = Regex.Replace(htmlCode, "^\s*", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
                    htmlCode = Regex.Replace(htmlCode, "\r\n", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
                    htmlCode = Regex.Replace(htmlCode, "<!--*.*?-->", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
                }
                //保存文件,这里不能用File.WriteAllText
                File.AppendAllText(htmlPath, htmlCode);
            }
        }
    }

    3、确保静态页面数据的及时性

    当在后台管理系统中,对某个栏目或某篇文章进行过增删改的操作时,要同时保证静态页面中的数据与数据库中的数据保持一致。

    最初想到的实现方法是在静态页面中设定一个过期时间,但是公司所使用的框架中内容信息是通过异步加载进来的,所以保存的静态页面中不存<html><head><body>标签,所以就放弃了这种方法。因为项目时间关系,最后偷了一点懒,在后台管理中添加一个“重新发布”的功能,直接将之前生成的静态页面全部删除掉。

  • 相关阅读:
    进程间通信(一):竞争条件与相互排斥方案
    (素材源代码) 猫猫学iOS 之UIDynamic重力、弹性碰撞吸附等现象牛逼Demo
    <html>
    模运算的规则
    ubuntu16.04重置root密码
    rancheros在vm主机部署
    基于centos7.6离线部署开k3s
    centos7.6在线yum安装docker-ce
    centos在线安装ffmpeg
    tar.bz2解压异常
  • 原文地址:https://www.cnblogs.com/tracine0513/p/4933440.html
Copyright © 2011-2022 走看看