我试图让我的MVC控制器返回存储在Azure Blob容器中的PDF。客户端的浏览器将很好地下载PDF,但是当他们打开PDF时,他们会看到“无法加载PDF文档错误”。在Chrome中打开文件时(尽管该文件也无法在其他浏览器中打开)。
我能够执行以下操作将文件下载到我的计算机上并打开它:
public static void DownloadFile()
{
CloudBlockBlob cloudBlockBlob =
CloudBlobContainer.GetBlockBlobReference("document.pdf");
AsyncCallback callback = new AsyncCallback(DownloadComplete);
cloudBlockBlob.BeginDownloadToFile(@"path\document.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)进行此操作,并且在图像损坏或无法打开时也遇到了类似的问题。然后我收到的错误是“看来我们不支持此文件格式”。
更新:有关如何使它工作的信息,请参见下面的解决方案。
答案 0 :(得分:1)
对此的解决方案来自以下链接:Open a pdf file(using bytes) stored in Azure Blob storage
我最终只是将字节流从Azure转储到响应的输出流中。但是,您需要确保将响应的内容类型设置为“ application / 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);
}