首先,感谢武眉博<活靶子.Net>的博客[2007最后一博]Url地址重写,利用HttpHander手工编译页面并按需生成静态HTML文件给我提供了很大的帮助。

最近,项目中DesignStudio页面的初始加载速度比较慢,想要提升一下页面加载的性能。
Team对代码做了很多改进,包括减少数据库访问,加Cache等,最终还是没能达到客户的满意。
然后浏览了很多国内外的e-commerce网站,发现大多数都使用HTML页面来提升页面加载性能。
最终决定尝试变换思路,用HTML页面来提升性能,以满足客户需求。

由于每个Item的Personalize功能都会使用DesignStudio页面,只是改变一下页面的QueryString,所以只有核心部分的生成HTML功能采纳了武眉博的代码思路,其他的业务逻辑还是依据项目的实际情况进行设计。

下面把我觉得在开发过程中需要注意的地方记录下来,希望能帮助有可能涉及到这方面开发工作的朋友。如有任何错误,还请不吝赐教。

1.上面提到由于所有的Item都会使用DesignStudio页面进行Personalize,所以我直接将这个页面映射到一个HttpHandler,免去了httpModules和UrlMappings的配置。

<httpHandlers>
    <add path="DesignStudio.aspx" verb="*" type="AspxBoy.BuildHtmlDemo.ToHtmlHandler"/>
</httpHandlers>

2.由于是通过QueryString判断是否生成HTML文件,所以可以直接使用context对象获取QueryString就OK了。
3.BuildManager.CreateInstanceFromVirtualPath方法的第一个参数需要传入不带QueryString的aspx页面路径。

public void ProcessRequest(HttpContext context)
        {
            string rawUrl = context.Request.RawUrl;
            string htmlPath = context.Request.PhysicalApplicationPath;
            string path = context.Request.Path;
            string folder = "StaticHTML";

            string paramAction = context.Request.QueryString["ACTION"];
            string sku = context.Request.QueryString["SKU"];
            string filename = folder + "\\" + sku + ".html";

            if (!Directory.Exists(htmlPath + folder))
            {
                Directory.CreateDirectory(htmlPath + folder);
            }

            if (!string.IsNullOrWhiteSpace(paramAction))
            {
                if (paramAction.ToLower() == "create")
                {
                    string htmlFile = htmlPath + filename;
                    if (!File.Exists(htmlFile))
                    {
                        IHttpHandler handler =
                            BuildManager.CreateInstanceFromVirtualPath(path, typeof (Page)) as
                            IHttpHandler;
                        handler.ProcessRequest(context);
                        context.Response.Filter = new Filter(context.Response.Filter, htmlFile);
                    }
                    else
                    {
                        context.Server.Transfer(filename);
                    }
                }
                else if (paramAction.ToLower() == "edit")
                {
                    IHttpHandler handler = BuildManager.CreateInstanceFromVirtualPath(path, typeof (Page)) as IHttpHandler;
                    handler.ProcessRequest(context);
                }
            }
        }
public class Filter : Stream
    {
        private Stream _sink;
        private long _position;
        private string filePath;
        private FileStream _tempFileStream;
        private BinaryWriter _writer;
        byte[] _buffer;
        int _count;

        public Filter(Stream sink, string file)
        {
            _sink = sink;
            filePath = file;
        }

        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 0; }
        }

        public override long Position
        {
            get { return _position; }
            set { _position = value; }
        }

        public override long Seek(long offset, System.IO.SeekOrigin direction)
        {
            return _sink.Seek(offset, direction);
        }

        public override void SetLength(long length)
        {
            _sink.SetLength(length);
        }

        public override void Close()
        {
            if (_sink != null) _sink.Close();
            if (_tempFileStream != null) _tempFileStream.Close();
            if (_writer != null) _writer.Close();
        }

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

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

        private FileStream TempFileStream
        {
            get
            {
                if (_tempFileStream == null)
                {
                    _tempFileStream = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write);
                }
                return _tempFileStream;
            }
        }

        private BinaryWriter BWriter
        {
            get
            {
                if (_writer == null)
                {
                    string fileDirectory = filePath.Substring(0, filePath.LastIndexOf("\\"));
                    if (!Directory.Exists(fileDirectory))
                    {
                        Directory.CreateDirectory(fileDirectory);
                    }
                    _writer = new BinaryWriter(TempFileStream);
                }
                return _writer;
            }
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            if (HttpContext.Current.Response.ContentType == "text/html")
            {
                Encoding e = Encoding.GetEncoding(HttpContext.Current.Response.Charset);
                string pageStr = e.GetString(buffer, offset, count);
                _buffer = e.GetBytes(pageStr);
                _count = e.GetByteCount(pageStr);
                _sink.Write(_buffer, 0, _count);
                BWriter.Write(_buffer, 0, _count);
            }
            else
            {
                _sink.Write(buffer, offset, count);
            }
        }
    }

 

posted on 2014-01-08 13:09  snowleopard_kevin  阅读(184)  评论(0编辑  收藏  举报