Problems downloading pdf file from api web service

I am trying to configure a web api service that looks for a .pdf file in a directory and returns the file if it is found.

Controller

public class ProductsController : ApiController { [HttpPost] public HttpResponseMessage Post([FromBody]string certificateId) { string fileName = certificateId + ".pdf"; var path = @"C:\Certificates\20487A" + 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 call 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 seems to work in the sense that the download file dialog is displayed with the correct name and file size, etc., but the download takes only a couple of seconds (when the file size is> 30 MB) and the files are damaged when I try to open them .

Any ideas what I'm doing wrong?

+1
source share
1 answer

Your code is similar to what I used in the past, but below is what I usually 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 publish this for two reasons. One, add a title for the length of the content, you may need to indicate how large the file is, so the application expects an entire response.

If this does not fix it. Set a breakpoint, does the byte array correspond to the corresponding length (aka, 30 million bytes for a 30 megabyte file)? Did you use a violinist to find out how much content is returned by an HTTP call?

+1
source

Source: https://habr.com/ru/post/1235579/


All Articles