Problem Showing PDF files in Chrome with .Net Core MemoryStream

73 Views Asked by At

I have a file viewer (written in .Net Core 7) set up to display files from the filesystem, rather than a URL, using the MemoryStream (because user uploads are housed outside the root directory of the web site). Uploaded images at any size don't seem to be an issue and stream to the browser fine; serving PDFs to Chrome, however, returns an "Error--could not load PDF" in some cases, I think if the PDF is larger than some unknown size (maybe 400k? It's not consistent). Chrome is ok displaying smaller PDFs, but not arbitrarily larger ones. MS Edge shows all PDFs fine.

This file viewer is simply a page on the site, that gets the file defined filepath based on a GET request. Here's my code:

public void OnGet(string s)
{
    //... some other stuff, like retreiving the file path from the database ...

    //Retrieve uploaded filepath (which would be a full path, like "C:\some\path\to\file.pdf")
    this.GetFile(this.FileData.FileLocation);
}

public ActionResult GetFile(string FilePath)
{
if (System.IO.File.Exists(FilePath))
{
    //define the file extension and content type
    fileName = FilePath.Substring(FilePath.LastIndexOf("\\") + 1);
    fileExt = fileName.Substring(FilePath.LastIndexOf(".") + 1).ToUpper();
    contentType = "";
    switch (fileExt)
    {
        case "PDF":
            contentType = "application/pdf"; 
            break;
        case "TXT":
            contentType = "text/plain";
            break;
        case "DOC":
            contentType = "application/msword";
            break;
        case "DOCX":
            contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
            break;
        case "PNG":
            contentType = "image/png";
            break;
        case "JPG":
        case "JPEG":
            contentType = "image/jpeg";
            break;
    }

    // Read the file into a MemoryStream
    using (FileStream fileStream = System.IO.File.OpenRead(FilePath))
    {
        // Create a MemoryStream to hold the file data
        MemoryStream memoryStream = new MemoryStream();
        memoryStream.SetLength(fileStream.Length);
        memoryStream.Position = 0;
        fileStream.CopyTo(memoryStream);
        byte[] binaryData = memoryStream.ToArray();

        // Set response headers
        Response.Clear();
        Response.ContentType = contentType;
        Response.Headers.Add("Content-Disposition", $"inline; filename=\"{fileName}\"");
        Response.Headers.Add("Content-Length", binaryData.Length.ToString());

        // Write the binary data to the response body
        Response.Body.Write(binaryData, 0, binaryData.Length);

        // End the response
        Response.StatusCode = StatusCodes.Status200OK;
    }
}
else
{
    // Handle file not found
    return StatusCode(404);
}

return null; // Return null to prevent rendering a view
}

Like I said, smaller PDF files are displayed properly with Chrome's Acrobat handler, but then other files (even ones that seem really small, like 200-300kb) won't load, and instead return an error "Error Failed to load PDF document.", which appears to be shown from the Acrobat file handler in Chrome.

Chrome in Dev Tools -> Network, says it has 'stalled'. And I can see that, if I change the content-disposition to "attachement" instead of "inline", Chrome tries to download the file but is interrupted for whatever reason -- in the downloads dialog, any file in this state has a button asking if download should continue.

I've tried many permutations of this code block found on Stack as possible solutions, but still always the same result -- some pdfs can be viewed without issue, others show an error. So, I get that this is a Chrome issue, but I can't seem to determine the cause nor the resolution. Any help greatly appreciated!

0

There are 0 best solutions below