Reputation:
I have a ASP.NET MVC app with a controller action which is triggered by a button press on my view. The controller action in turn calls a ASP.NET Web API. The Web API calls a third, outside system and asks for a PDF to be created at a network location. The Web API then picks up the PDF from the network location, converts it into a byte array, and returns the byte array from the Web API.
I have verified the PDF is generated properly by the third party application. I went to the network location and could open the PDF successfully.
At this point, I am back in my original MVC controller action, with a byte array. I now need to return the byte array to the browser as a PDF file for direct download, versus opening the PDF file. I have found answers such as this suggesting using the WriteAllBytes method to write the file. In my case though, I don't want to write the file to disk but instead want to return the file as a download to the user.
Also, I am not sure if I need to decode the byte array in my MVC app before attempting to send to the user for download. Does the Web API encode it as Base64 when it returns it?
This is a simplified version of my Web API code:
public byte[] GetPdf (int accountNumber)
{
string filePath = _outsideServiceManager.RequestPdfCreation(accountNumber);
byte[] pdfBytes = System.IO.File.ReadAllBytes(filePath);
return pdfBytes;
}
And this is a simplified version of my MVC controller action code. I am using the overload of the Controller.File method which accepts a byte array.
public ActionResult DownloadPdf (int accountNumber)
{
byte[] pdfFileAsByteArray = _serviceManager.GetPdf(accountNumber);
return File(pdfFileAsByteArray, "application/pdf", "AccountSummary.pdf");
}
Right now I do successfully pick up the PDF file, convert it to a byte array, and successfully receive it in the MVC app. It does directly download to the user's browser, but when you try to open it with a PDF reader it says that the PDF file is corrupted.
How should I construct this flow?
EDIT: One observation I made was that the byte array might be 26 kb in the Web API, but closer to 34 kb when it is retrieved in the MVC app. Does this indicate encoding that has to be undone before accessing the file?
Upvotes: 3
Views: 5124
Reputation:
As Chris mentioned in a comment, the issue was with the response from the WebAPI. The byte array was automatically being encoded as a Base64 string, so when I tried to use that byte array in the client without decoding it first, it didn't work.
What I had to do was change my MVC app code to use ReadAsStringAsync versus ReadAsByteArrayAsync.
Then I had to remove the first and last character of the string as extra quotation marks were inserted for some reason, which would cause my subsequent conversion attempt to fail.
After that, I just used Convert.FromBase64String to decode the string and convert it into a byte array. The PDF files are now viewable.
Upvotes: 1
Reputation: 2861
I think what you'll need to do is have the WebApi response be a simple HttpResponseMessage, with a StreamContent inside. Then you can simply have MVC return the stream.
Upvotes: 0
Reputation: 5451
You need to add the extension to the filename parameter:
return File(pdfFileAsByteArray, "application/pdf", "AccountSummary");
should be
return File(pdfFileAsByteArray, "application/pdf", "AccountSummary.pdf");
Upvotes: 0