A BinaryContentResult for ASP.NET MVC

Today in work I had a requirement where I wanted to output binary content to the response output stream.  I also want to stay with the MVC Controller for serving this content and so wanted a result I could add my data to and return it.  To my knowledge there is a ContentResult, but with this the Content property is of type string, and is not what I wanted.  I this particular case, I am physically GZipping content and then writing out to the Response.OutputStream

Previous to this I have been seeing and using examples where you assign a GZipOutputStream as a Filter on the Response dynamically.  For some strange reason on the Live environment the header and filter where being ignored on the response yet on the test, builds and sandbox everything worked as expected and the dynamic resources got GZipped.

So I had to go another way and what I came up with was to physically GZip the output content and send it to the response with the accompanying header.  I cannot see why this would not work on the server as the content is physically being served already GZipped opposed to applying a filter which can obviously be removed somewhere in the pipeline.  Any way after some reading I found some evidence that a library, http://www.icsharpcode.net/OpenSource/SharpZipLib/ , yields far better results than the out of the box one from .NET, so for this example I have a dependency on this assembly.  Apart from that I have added a couple of properties which allow for the conditional Compression and also a list of headers to give a little more flexibility.  So here is the code:

    /// <summary>
    /// A content result which can accept binart data and will write to the output
    /// stream.  If GZip is set to true the content will be GZipped and the relevant
    /// header added to the response HTTP Headers
    /// </summary>
    public class BinaryContentResult : ActionResult
    {
        public byte[] Data { get; set; }
        public NameValueCollection Headers { get; set; }
        public bool Gzip { get; set; }


        public override void ExecuteResult(ControllerContext context)
        {
            foreach (string s in Headers.Keys)
            {
                context.HttpContext.Response.AddHeader(s, Headers[s]);
            }

            if (Gzip)
            {
                using (var os = new GZipOutputStream(context.HttpContext.Response.OutputStream))
                {
                    os.Write(Data, 0, Data.Length);
                }
                context.HttpContext.Response.AddHeader("Content-Encoding", "gzip");
                context.HttpContext.Response.AddHeader("X-Compressed-By", "Custom-Compressor");
            }
            else
            {
                context.HttpContext.Response.BinaryWrite(Data);
            }

            context.HttpContext.Response.End();
        }
    }
Published Tuesday, February 16, 2010 7:37 PM by REA_ANDREW
Filed under: , ,

Comments

# re: A BinaryContentResult for ASP.NET MVC

Wednesday, February 17, 2010 10:17 AM by robert.westerlund

Hi,

Have you had a look at the FileContentResult, which handles just that which you ask for, a byte array. If the files you load are large, perhaps the FileStreamResult would be even better since you potentially (depending on how you are storing the bytes) might not have to load the whole file into memory.

/Robert

# re: A BinaryContentResult for ASP.NET MVC

Wednesday, February 17, 2010 3:12 PM by REA_ANDREW

Ahhh nice one Robert.  I was not aware of that Class.  That does sound exactly what I required.  Thanks for the comment

# Dreamweaver MX: Advanced ASP Web Development ?? Web Development &#8230; | DevBlogr

Pingback from  Dreamweaver MX: Advanced ASP Web Development ?? Web Development &#8230; | DevBlogr

# .NET Pulse 2/18/2010

Thursday, February 18, 2010 11:35 AM by Cadred (dotNET)

.NET Pulse 2/18/2010

# Microsoft ASP.NET MVC 2: The New Stuff | .NET Software Development &#8230; | ASP WebDev Insider

Pingback from  Microsoft ASP.NET MVC 2: The New Stuff | .NET Software Development &#8230; | ASP WebDev Insider

Leave a Comment

(required) 
(required) 
(optional)
(required)