Problems with downloading pdf file from web api service

I’m trying to set up a web api service that searches for a .pdf file in a directory and returns the file if it’s found.

The controller

public class ProductsController : ApiController
{

    [HttpPost]
    public HttpResponseMessage Post([FromBody]string certificateId)
    {
        string fileName = certificateId + ".pdf";
        var path = @"C:Certificates20487A" + fileName;

        //check the directory for pdf matching the certid
        if (File.Exists(path))
        {
            //if there is a match then return the file
            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
            var stream = new FileStream(path, FileMode.Open);
            stream.Position = 0;
            result.Content = new StreamContent(stream);
            result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = fileName };
            result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
            result.Content.Headers.ContentDisposition.FileName = fileName;
            return result;
        }
        else
        {
            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.Gone);
            return result;
        }
    }
}

I’m calling the service with the following code

private void GetCertQueryResponse(string url, string serial)
{
    string encodedParameters = "certificateId=" + serial.Replace(" ", "");

    HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url);

    httpRequest.Method = "POST";
    httpRequest.ContentType = "application/x-www-form-urlencoded";
    httpRequest.AllowAutoRedirect = false;

    byte[] bytedata = Encoding.UTF8.GetBytes(encodedParameters);
    httpRequest.ContentLength = bytedata.Length;

    Stream requestStream = httpRequest.GetRequestStream();
    requestStream.Write(bytedata, 0, bytedata.Length);
    requestStream.Close();

    HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();

    if (response.StatusCode == HttpStatusCode.OK)
    {

        byte[] bytes = null;
        using (Stream stream = response.GetResponseStream())
        using (MemoryStream ms = new MemoryStream())
        {
            int count = 0;
            do
            {
                byte[] buf = new byte[1024];
                count = stream.Read(buf, 0, 1024);
                ms.Write(buf, 0, count);
            } while (stream.CanRead && count > 0);
            ms.Position = 0;
            bytes = ms.ToArray();
        }

        var filename = serial + ".pdf";

        Response.ContentType = "application/pdf";
        Response.Headers.Add("Content-Disposition", "attachment; filename="" + filename + """);
        Response.BinaryWrite(bytes);
    }
}

This appears to be working in the sense that the download file dialogue is shown with the correct file name and size etc, but the download takes only a couple of seconds (when the file sizes are >30mb) and the files are corrupt when I try to open them.

Any ideas what I’m doing wrong?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Your code looks similar to what Ive used in the past, but below is what I typically use:

    Response.AddHeader("content-length", myfile.Length.ToString())
    Response.AddHeader("content-disposition", "inline; filename=MyFilename")
    Response.AddHeader("Expires", "0")
    Response.AddHeader("Pragma", "Cache")
    Response.AddHeader("Cache-Control", "private")

    Response.ContentType = "application/pdf"

    Response.BinaryWrite(finalForm)

I post this for 2 reasons. One, add the content-length header, you may have to indicate how large the file is so the application waits for the whole response.

If that doesn’t fix it. Set a breakpoint, does the byte array content the appropriate length (aka, 30 million bytes for a 30 MB file)? Have you used fiddler to see how much content is coming back over the HTTP call?


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x