我正在尝试让我的MVC控制器返回存储在Azure Blob容器中的PDF。客户端的浏览器将很好地下载PDF,但是当他们打开它时,在Chrome中打开它时,他们会看到"加载PDF文档错误失败"(尽管该文件也无法在其他浏览器中打开)。
我能够在我的机器上下载该文件并执行以下操作打开它:
public static void DownloadFile()
{
CloudBlockBlob cloudBlockBlob =
CloudBlobContainer.GetBlockBlobReference("document.pdf");
AsyncCallback callback = new AsyncCallback(DownloadComplete);
cloudBlockBlob.BeginDownloadToFile(@"pathdocument.pdf", FileMode.Create,
callback, new object());
}
但是,我宁愿不在服务器上创建任何临时文件并返回这些文件。我想在内存中创建它们并将其返回给客户端。
我的控制器代码:
public async Task<FileStreamResult> Test()
{
MemoryStream stream = await BlobStorageUtils.DownloadFile();
return File(stream, "application/pdf", "document.pdf");
}
用于从 Blob 容器检索文件的代码
public static async Task<MemoryStream> DownloadFile()
{
CloudBlockBlob cloudBlockBlob =
CloudBlobContainer.GetBlockBlobReference("document.pdf");
MemoryStream stream = new MemoryStream();
await cloudBlockBlob.DownloadToStreamAsync(stream);
return stream;
}
正如我提到的,我的文件在浏览器中下载正常,但是在尝试打开文件时收到错误。
最终,我希望它适用于任何类型的文档,而不仅仅是PDF。
编辑:我应该注意,我也对图像文件(特别是PNG)进行了尝试,并且遇到了类似的问题,即图像已损坏或无法打开。我当时收到的错误是"看起来我们不支持这种文件格式"。
更新:请参阅下面的解决方案,了解我如何使其工作。
解决方案来自此链接: 打开存储在 Azure Blob 存储中的 pdf 文件(使用字节)
我最终只是将字节流从 Azure 转储到响应的输出流中。但是,您需要确保响应的内容类型设置为"应用程序/pdf"。我的代码是这样的:
控制器代码:
public async Task<ActionResult> Test()
{
Response.Buffer = true;
Response.Clear();
Response.ContentType = "application/pdf";
await BlobStorageUtils.DownloadFile(Response.OutputStream);
return new EmptyResult();
}
用于从 Blob 容器检索文件的代码
public static async Task DownloadFile(Stream outputStream)
{
CloudBlockBlob cloudBlockBlob =
CloudBlobContainer.GetBlockBlobReference("document.pdf");
await cloudBlockBlob.DownloadToStreamAsync(outputStream);
}