In my MVC application, I have enabled gzip compression for all responses. If you are reading this binary write from an ajax call with gzipped responses, you are getting the gzipped bytearray rather than original bytearray that you need to work with.
//c# controller is compressing the result after the response.binarywrite
[compress]
public ActionResult Print(int id)
{
...
var byteArray=someService.BuildPdf(id);
return return this.PDF(byteArray, "test.pdf");
}
//where PDF is a custom actionresult that eventually does this:
public class PDFResult : ActionResult
{
...
public override void ExecuteResult(ControllerContext context)
{
//Set the HTTP header to excel for download
HttpContext.Current.Response.Clear();
//HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AddHeader("content-disposition", string.Concat("attachment; filename=", fileName));
HttpContext.Current.Response.AddHeader("Content-Length", pdfBytes.Length.ToString());
//Write the pdf file as a byte array to the page
HttpContext.Current.Response.BinaryWrite(byteArray);
HttpContext.Current.Response.End();
}
}
//javascript
function pdf(mySearchObject) {
return $http({
method: 'Post',
url: '/api/print/',
data: mySearchObject,
responseType: 'arraybuffer',
headers: {
'Accept': 'application/pdf',
}
}).then(function (response) {
var type = response.headers('Content-Type');
//if response.data is gzipped, this blob will be incorrect. you have to uncompress it first.
var blob = new Blob([response.data], { type: type });
var fileName = response.headers('content-disposition').split('=').pop();
if (window.navigator.msSaveOrOpenBlob) { // for IE and Edge
window.navigator.msSaveBlob(blob, fileName);
} else {
var anchor = angular.element('<a/>');
anchor.css({ display: 'none' }); // Make sure it's not visible
angular.element(document.body).append(anchor); // Attach to document
anchor.attr({
href: URL.createObjectURL(blob),
target: '_blank',
download: fileName
})[0].click();
anchor.remove();
}
});
}
" var blob = new Blob([response.data], { type: type }); "
This will give you that invalid/corrupt file that you are trying to open when you turn that byte array into a file in your javascript if you don't uncompress it first.
To fix this, you have a choice to either prevent gzipping this binary data so that you can properly turn it into the file that you are downloading, or you have to decompress that gzipped data in your javascript code before you turn it into a file.