Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return delayed stream from MVC

I have an MVC action which currently returns a PDF:

return File(File.OpenRead(pdfPath), "application/pdf");

This is a simplification. If the file exists then we go straight to OpenRead but in other cases it needs to first be retrieved or generated. It's this part that can cause a substantial delay for the client waiting for the HTTP response.

I'm wondering if there's a way with MVC to return the stream immediately but only start writing to it once the file is available.

This way the PDF client (chromes built in) will show the loading spinner from the start and not just while the stream is actively transfering.

like image 717
Daniel Revell Avatar asked Oct 31 '22 21:10

Daniel Revell


1 Answers

I don't think it's possible to return the stream immediately, at least not within the MVC model, but you can return the headers at least so the client knows something's coming. Here's an example:

public void SO32070323()
{
    var file = new FileInfo(@"J:\Projects\XibisAutoGenTests\IansAwesomeSite\private\test.pdf");

    Response.AddHeader("Content-Disposition", "inline;filename=somefile.pdf");
    Response.AddHeader("Content-Length", file.Length.ToString());
    Response.Flush();
    Thread.Sleep(5000);

    Response.TransmitFile(file.FullName);

}

This way you send the content length and disposition so the client knows a file is coming. You can then send the actual file content later.

Please note most clients are likely to have a timeout, so you can't wait forever before sending the content. The timeout is likely to differ per client, but I expect if you can send the content within 30 seconds you'll be OK.

like image 141
Ian Newson Avatar answered Nov 15 '22 08:11

Ian Newson