Overview

Some people like to have a compressed output of there WebForms or MVC-Pages in .NET. The following snippet shows such a compressor. It is not optimized for performance but you should see the principle behind. The compressor takes care of <pre><code>. You may also use this compressor to remove unwanted html snippets from your MVC or WebForm pages.

Some people like to have a compressed output of there WebForms or MVC-Pages in .NET. The following snippet shows such a compressor. It is not optimized for performance but you should see the principle behind. The compressor takes care of <pre><code>. You may also use this compressor to remove unwanted html snippets from your MVC or WebForm pages.

Snippet

Handler Module

using System.Linq;

namespace ProCompressor
{
    using System;
    using System.IO;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Web;

    public sealed class CompressionModule : IHttpModule
    {
        #region non public members

        private static void ContextBeginRequest(object sender, EventArgs e)
        {
            var app = sender as HttpApplication;
            if (app != null) if (app.Request.AcceptTypes != null && app.Request.AcceptTypes.Contains("text/html") && !app.Request.RawUrl.Contains("/Admin/")) app.Response.Filter = new CompressorBuffered(app.Response.Filter);
        }

        #endregion

        #region IHttpModule Members

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

        #endregion

        #region Non Public Nested type: CompressorBuffered

        private class CompressorBuffered : Stream
        {
            #region fields

            private readonly MemoryStream memoryStream;
            private readonly Stream stream;

            #endregion

            #region constructors

            public CompressorBuffered(Stream stream)
            {
                this.stream = stream;
                this.memoryStream = new MemoryStream();
            }

            #endregion

            #region public properties

            public override bool CanRead { get { return this.stream.CanRead; } }
            public override bool CanSeek { get { return this.stream.CanSeek; } }
            public override bool CanWrite { get { return this.stream.CanWrite; } }
            public override long Length { get { return this.stream.Length; } }
            public override long Position { get; set; }

            #endregion

            #region public members

            public override void Close()
            {
                var data = this.memoryStream.ToArray();
                var content = Encoding.UTF8.GetString(data);
                content = CompressHtml(content);
                var output = Encoding.UTF8.GetBytes(content);
                this.stream.Write(output, 0, output.GetLength(0));
                this.stream.Close();
            }

            public override void Flush() { this.stream.Flush(); }
            public override int Read(byte[] buffer, int offset, int count) { return this.stream.Read(buffer, offset, count); }
            public override long Seek(long offset, SeekOrigin origin) { return this.stream.Seek(offset, origin); }
            public override void SetLength(long value) { this.stream.SetLength(value); }
            public override void Write(byte[] buffer, int offset, int count) { this.memoryStream.Write(buffer, offset, count); }

            #endregion

            #region non public members

            private static string CompressHtml(string content)
            {
                var matches = Regex.Matches(content, "<pre>.*</pre>", RegexOptions.Singleline).Cast<Match>().ToList();
                content = Regex.Replace(content, "^\\s*", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
                content = Regex.Replace(content, "\\r\\n", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
                content = Regex.Replace(content, "\\n", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
                content = Regex.Replace(content, "<!--*.*?-->", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
                content = content.Replace("<![CDATA[", "<![CDATA[" + Environment.NewLine);
                content = content.Replace("//]]>", Environment.NewLine + "//]]>");
                content = content.Replace("\t", " ");
                var i = 0;
                content = Regex.Replace(
                    content,
                    "<pre>.*</pre>",
                    (match) =>
                        {
                            try
                            {
                                return matches[i].Value;
                            }
                            finally
                            {
                                i += 1;
                            }
                        },
                    RegexOptions.Singleline);
                foreach (var match in matches)
                {                    
                }
                return content;
            }

            #endregion
        }

        #endregion
    }
}

Web.Config Extension

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="false">
      <remove name="CompressionModule" />
      <add name="CompressionModule" type="ProCompressor.CompressionModule" />
    </modules>