从ASP.NET Core 2控制器返回PDF

3

我正在尝试从我的ASP.NET Core 2控制器返回一个PDF文件。 我有这段代码(大部分来自这个SO问题):

var net = new System.Net.WebClient();
//a random pdf file link
var fileLocation = "https://syntera.io/documents/T&C.pdf";/
var data = net.DownloadData(fileLocation);
MemoryStream content = null;
try
{
    content = new MemoryStream(data);
    return new FileStreamResult(content, "Application/octet-stream");
}
finally
{
    content?.Dispose();
}

上面的代码是我的控制器调用的服务类的一部分。这是来自我的控制器的代码。

public async Task<IActionResult> DownloadFile(string fileName)
{
    var result = await _downloader.DownloadFileAsync(fileName);
    return result;
}

但我一直收到 ObjectDisposedException: Cannot access a closed Stream. 的错误。

尝试和最终块是从另一个SO问题中的修复尝试。

主要问题是A)这是将PDF文件发送回浏览器的正确方法吗?B)如果不是,如何更改代码以将PDF发送到浏览器?

理想情况下,我不想先将文件保存在服务器上,然后再将其返回到控制器。我宁愿在内存中保留所有内容并返回它。


1
在添加 try/finally 之前的确切代码是什么?那个 try/finally 肯定会引起 ObjectDisposedException,因此看看在引入它之前发生了什么会很有用。 - Kirk Larkin
2个回答

5
finally 语句块总是会被调用(即使 return 语句之后),因此它会在内容流发送到客户端之前始终处理掉该流,这就是错误的原因。

理想情况下,我不希望先将文件保存在服务器上,然后再将其返回给控制器。我宁愿在内存中保留所有内容并返回它。

使用 FileContentResult 类来获取原始字节数组数据并直接返回它。

FileContentResult: 表示一个 ActionResult,当执行时将向响应中写入一个二进制文件。

async Task<IActionResult> DownloadFileAsync(string fileName){
    using(var net = new System.Net.WebClient()) {
        byte[] data = await net.DownloadDataTaskAsync(fileName);
        return new FileContentResult(data, "application/pdf") {
            FileDownloadName = "file_name_here.pdf"
        };
    }
}

不需要额外的内存流


1

您必须指定:

Response.AppendHeader("content-disposition", "inline; filename=file.pdf");
return new FileStreamResult(stream, "application/pdf")

为了让文件能够在浏览器中直接打开


这确实对ObjectDisposedException没有帮助。 - Kirk Larkin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接