deruitda
deruitda

Reputation: 580

'Error Failed to Load PDF Document' when Returning PDF From Azure Blob Storage

I am trying to get my MVC controller to return a PDF stored in an Azure Blob Container. The client's browser will download the PDF fine, but when they open it they will see "Error Failed to load PDF document." when opening it in Chrome (though the file does not open in other browsers either).

I was able to download the file on my machine and open it fine doing the following:

public static void DownloadFile()
{
    CloudBlockBlob cloudBlockBlob = 
                   CloudBlobContainer.GetBlockBlobReference("document.pdf");

    AsyncCallback callback = new AsyncCallback(DownloadComplete);
    cloudBlockBlob.BeginDownloadToFile(@"path\document.pdf", FileMode.Create, 
    callback, new object());
}

However I would rather not create any temp files on the server and return those. I would like to just create them in memory and return that to the client.

My Controller Code:

public async Task<FileStreamResult> Test()
{
    MemoryStream stream = await BlobStorageUtils.DownloadFile();
    return File(stream, "application/pdf", "document.pdf");
}

The code to retrieve the file from the Blob Container

public static async Task<MemoryStream> DownloadFile()
{
    CloudBlockBlob cloudBlockBlob = 
                   CloudBlobContainer.GetBlockBlobReference("document.pdf");
    MemoryStream stream = new MemoryStream();
    await cloudBlockBlob.DownloadToStreamAsync(stream);
    return stream;
}

As I mentioned, my file downloads in the browser fine, but I receive the error when trying to open the file.

Eventually I would like this to work with any type of document, not just PDFs.

Edit: I should note that I have tried this with image files as well (PNG specifically) and had a similar issue where the image was corrupted or couldn't be opened. The error I received then was "It looks like we don't support this file format".

Update: See my solution below for how I got this to work.

Upvotes: 2

Views: 4006

Answers (1)

deruitda
deruitda

Reputation: 580

The solution for this came from this link: Open a pdf file(using bytes) stored in Azure Blob storage

I ended up just dumping the byte stream from Azure into the response's output stream. However you need to make sure that the content type of the response is set to "application/pdf". My code ended up like this:

Controller Code:

public async Task<ActionResult> Test()
{
     Response.Buffer = true;
     Response.Clear();
     Response.ContentType = "application/pdf";

     await BlobStorageUtils.DownloadFile(Response.OutputStream);

     return new EmptyResult();
}

Code to retrieve file from Blob Container

public static async Task DownloadFile(Stream outputStream)
{
    CloudBlockBlob cloudBlockBlob = 
                                CloudBlobContainer.GetBlockBlobReference("document.pdf");
    await cloudBlockBlob.DownloadToStreamAsync(outputStream);
}

Upvotes: 1

Related Questions