0

I have a MVC controller which is returning a File result as follows

<pre>
public ActionResult GetPdf(string id)
        {
            string fileName = Server.MapPath("Somepdf.pdf");
            FileInfo info = new FileInfo(fileName);
            return File(info.OpenRead(), "application/pdf");
        }
</pre>

This is read by an iOS app and this works fine.

But now I want to change this to stream the file from Amazon S3. I can get the stream from S3 easily but no matter what I return in the method, the iOS app does not like it.

<pre>
Stream pdfFrom = S3Interface.getstream("Pdfs/somepdf.pdf");
return File(pdfFrom, "application/pdf", "somepdfname.pdf");
</pre>

Ive tried numerous ways but cant seem to get the result to be valid.

I though I was close with this post by changing the result to a byte[] but still no joy as this doesnt seem to return all the bytes. Returning a stream from File.OpenRead()

System.IO.MemoryStream data = new System.IO.MemoryStream();
System.IO.Stream str = S3Interface.getstream("Pdfs/somepdf.pdf");

str.CopyTo(data);
data.Seek(0, SeekOrigin.Begin);
byte[] buf = new byte[data.Length];
data.Read(buf, 0, buf.Length);

return data.ToArray();

What I basically need is the equivalent to File.OpenRead but for a Stream.

Any advice appreciated

Community
  • 1
  • 1
Raj
  • 717
  • 8
  • 25
  • What are you doing with the data returned from the Controller on the iOS side? What error or result are you seeing from iOS? If you call the same URI from a browser does the data look good coming back? – Belogix Aug 14 '13 at 10:17
  • The data returned to iOS is basically rendering the pdf on screen. So this works when returning it as a FILE which from what I understand is a FileStreamResult but when I do this from a remote file, it doesnt seem to like it? Im definitely getting data back from my filestream so thats not the problem but im not sure why it wouldnt render the data? – Raj Aug 14 '13 at 10:51
  • When calling from a browser does the PDF save correctly using first and/or second approach? Trying to pin down whether it is an iOS issue. – Belogix Aug 14 '13 at 10:54
  • Method 1, yes. Method 2 no. It just returns a response saying 'System.Byte[]' so Im pretty sure this is an issue with my method not returning the file in its entirety. – Raj Aug 14 '13 at 11:03
  • Also, I tried changing the return type to return new FileStreamResult(str, "application/pdf"); - this seems to open the pdf viewer in the browser but again, the pdf does not open. – Raj Aug 14 '13 at 11:08
  • Suggests that the header is correct (MIME type etc) but the contents is rubbish. Have you tried debugging and stepping through to check the stream contents looks good? I think you've narrowed it down and if you can get it working in browser you'll be good on iOS! – Belogix Aug 14 '13 at 11:14
  • Yup you were right, and I found the issue. I had to 'rewind' the stream. str.Seek(0, SeekOrigin.Begin); return new FileStreamResult(str, "application/pdf"); – Raj Aug 14 '13 at 12:34
  • Brilliant! Glad I could help! – Belogix Aug 14 '13 at 12:36
  • On another note, the reason I was trying to do this via S3 is that the PDF is large (300mb+) and while it is streaming it, it obviously locks up IIS. Is there a way to let IIS just handle the request but then distribute the load of actually serving up the PDF stream? I could have 1000's of users at one time accessing the PDF and from what I can see at the moment only a few can download it simultaneously? – Raj Aug 14 '13 at 12:40
  • If you are using .NET 4.5 you could look into `async` / `await` so that your controller action is done asynchronously and not lock IIS threads up until it has completed the download. – Belogix Aug 14 '13 at 13:11

0 Answers0