4

Environment: .Net 3.5, jQuery 2.1.4

The result Hello, World comes back in the callback, but is there a way to make it come back as an attachment?

jquery:

function test() {
    $.ajax({
        type: "POST",
        url: "Handler1.ashx",
        contentType: "application/json; charset=utf-8",
        success: function (data) {
            $('#progressBar').hide();
            //alert(data);                
        }
    });

generic handler:

public class Handler1 : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            //Create and populate a memorystream with the contents of the 
            //database table 
            System.IO.MemoryStream mstream = GetData();
            //Convert the memorystream to an array of bytes. 
            byte[] byteArray = mstream.ToArray();
            //Clean up the memory stream 
            mstream.Flush();
            mstream.Close();
            // Clear all content output from the buffer stream 
            context.Response.Clear();
            // Add a HTTP header to the output stream that specifies the default filename 
            // for the browser's download dialog 
            context.Response.AddHeader("Content-Disposition", "attachment; filename=mytextfile.txt");
            // Add a HTTP header to the output stream that contains the 
            // content length(File Size). This lets the browser know how much data is being transfered 
            context.Response.AddHeader("Content-Length", byteArray.Length.ToString());
            // Set the HTTP MIME type of the output stream 
            context.Response.ContentType = "application/octet-stream";
            // Write the data out to the client. 
            context.Response.BinaryWrite(byteArray);
        }

        private MemoryStream GetData()
        {
            //Create the return memorystream object that will hold 
            //the buffered data. 
            MemoryStream ReturnStream = new MemoryStream();
            try
            {
                Thread.Sleep(5000); //Simulate some work.

                StreamWriter sw = new StreamWriter(ReturnStream);

                //Write the row of data to the Memory Stream. 
                sw.WriteLine("Hello, World");

                //Clean up the stream writer 
                sw.Flush();
                sw.Close();
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
            //Return the memory Stream 
            return ReturnStream;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

Resources:
http://www.c-sharpcorner.com/article/downloading-data-as-a-file-from-a-memorystream-using-a-http/

Rod
  • 14,529
  • 31
  • 118
  • 230

1 Answers1

5

jQuery ajax is not able to handle binary responses properly (can't set responseType), so it's better to use a plain XMLHttpRequest call

var xhr = new XMLHttpRequest();
xhr.open('POST', "Handler1.ashx", true);
xhr.responseType = 'arraybuffer';
xhr.onload = function ()
{
    if (this.status === 200)
    {
        var filename = "";
        var disposition = xhr.getResponseHeader('Content-Disposition');
        if (disposition && disposition.indexOf('attachment') !== -1)
        {
            var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
            var matches = filenameRegex.exec(disposition);
            if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
        }
        var type = xhr.getResponseHeader('Content-Type');

        var blob = new Blob([this.response], { type: type });
        if (typeof window.navigator.msSaveBlob !== 'undefined')
        {
            // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
            window.navigator.msSaveBlob(blob, filename);
        }
        else
        {
            var URL = window.URL || window.webkitURL;
            var downloadUrl = URL.createObjectURL(blob);

            if (filename)
            {
                // use HTML5 a[download] attribute to specify filename
                var a = document.createElement("a");
                // safari doesn't support this yet
                if (typeof a.download === 'undefined')
                {
                    window.location = downloadUrl;
                }
                else
                {
                    a.href = downloadUrl;
                    a.download = filename;
                    document.body.appendChild(a);
                    a.click();
                }
            }
            else
            {
                window.location = downloadUrl;
            }

            setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
        }
    }
    else
    {
        // Handle Error Here
    }
};
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send($.param($(frm).serializeArray()));
}

You can get more help here :-)

Community
  • 1
  • 1
Tapas Thakkar
  • 845
  • 8
  • 19