在具有名称的浏览器中使用 ASP.NET MVC FileContentResult 流文件?
有没有办法在浏览器中使用特定名称的 ASP.NET MVC FileContentResult 流式传输文件?
我注意到您可以使用 FileDialog(打开/保存),也可以在浏览器窗口中流式传输文件,但是当您尝试保存文件时它将使用 ActionName。
我有以下场景:
byte[] contents = DocumentServiceInstance.CreateDocument(orderId, EPrintTypes.Quote);
result = File(contents, "application/pdf", String.Format("Quote{0}.pdf", orderId));
当我使用它时,我可以流式传输字节,但会向用户提供一个打开/保存文件对话框。我想在浏览器窗口中实际流式传输该文件。
如果我只使用 FilePathResult,它会在浏览器窗口中显示该文件,但是当我单击“保存”按钮将文件保存为 PDF 时,它会显示操作名称作为文件名。
有人遇到过这种情况吗?
Is there a way to stream a file using ASP.NET MVC FileContentResult within the browser with a specific name?
I have noticed that you can either have a FileDialog (Open/Save) or you can stream the file in a browser window, but then it will use the ActionName when you try to save the file.
I have the following scenario:
byte[] contents = DocumentServiceInstance.CreateDocument(orderId, EPrintTypes.Quote);
result = File(contents, "application/pdf", String.Format("Quote{0}.pdf", orderId));
When I use this, I can stream the bytes, but a OPEN/SAVE file dialog is given to the user. I would like to actually stream this file in a browser window.
If I just use the FilePathResult, it shows the file in a browser window, but then when I click on "Save" button to save the file in PDF, it shows me the Action Name as the name of the file.
Has anyone encountered this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
要在浏览器中打开 PDF,您需要设置
Content-Disposition
标头:and for opening the PDF inside the browser you will need to set the
Content-Disposition
header:实际上,最简单的方法是执行以下操作......
Actually, the absolutely easiest way is to do the following...
这可能对其他面临此问题的人有所帮助。我终于找到了解决办法。事实证明,即使我们使用内联“内容处置”并指定文件名,浏览器仍然不使用该文件名。相反,浏览器会尝试根据路径/URL 解释文件名。
您可以通过此 URL 进一步阅读:
使用正确的文件名在浏览器中安全下载文件
这给了我一个我的想法是,我刚刚创建了 URL 路由,它将转换 URL 并以我想要提供给文件的文件名结尾。例如,我原来的控制器调用只是传递正在打印的订单的订单 ID。我期望文件名的格式为 Order{0}.pdf,其中 {0} 是订单 ID。同样,对于报价,我想要 Quote{0}.pdf。
在我的控制器中,我只是继续添加一个附加参数来接受文件名。我将文件名作为 URL.Action 方法中的参数传递。
然后,我创建了一条新路线,将该 URL 映射到以下格式:
http://localhost/ShoppingCart/PrintQuote/1054/Quote1054.pdf
这几乎解决了我的问题。
This might be helpful for whoever else faces this problem. I finally figured out a solution. Turns out, even if we use the inline for "content-disposition" and specify a file name, the browsers still do not use the file name. Instead browsers try and interpret the file name based on the Path/URL.
You can read further on this URL:
Securly download file inside browser with correct filename
This gave me an idea, I just created my URL route that would convert the URL and end it with the name of the file I wanted to give the file. So for e.g. my original controller call just consisted of passing the Order Id of the Order being printed. I was expecting the file name to be of the format Order{0}.pdf where {0} is the Order Id. Similarly for quotes, I wanted Quote{0}.pdf.
In my controller, I just went ahead and added an additional parameter to accept the file name. I passed the filename as a parameter in the URL.Action method.
I then created a new route that would map that URL to the format:
http://localhost/ShoppingCart/PrintQuote/1054/Quote1054.pdf
This pretty much solved my issue.
以前的答案是正确的:添加行...
...将导致多个 Content-Disposition 标头发送到浏览器。如果您为其提供文件名,则
FileContentResult
会在内部应用标头,从而发生这种情况。另一种非常简单的解决方案是简单地创建FileContentResult
的子类并重写其ExecuteResult()
方法。下面的示例实例化了 System.Net.Mime.ContentDisposition 类的实例(与内部 FileContentResult 实现中使用的同一对象)并将其传递到新类中:在您的
Controller
或基本Controller
中,您可以编写一个简单的帮助器来实例化FileContentResultWithContentDisposition
,然后从操作方法中调用它,像这样:现在文件将被发送到浏览器,文件名是您选择的,内容配置标头为“inline; filename=[filename]”。
我希望这有帮助!
Previous answers are correct: adding the line...
...will causing multiple Content-Disposition headers to be sent down to the browser. This happens b/c
FileContentResult
internally applies the header if you supply it with a file name. An alternative, and pretty simple, solution is to simply create a subclass ofFileContentResult
and override itsExecuteResult()
method. Here's an example that instantiates an instance of theSystem.Net.Mime.ContentDisposition
class (the same object used in the internalFileContentResult
implementation) and passes it into the new class:In your
Controller
, or in a baseController
, you can write a simple helper to instantiate aFileContentResultWithContentDisposition
and then call it from your action method, like so:Now the file will be sent to the browser with the file name you choose and with a content-disposition header of "inline; filename=[filename]".
I hope that helps!
使用 ASP.NET MVC 将文件流式传输到浏览器的绝对最简单的方法是:
这比 @azarc3 建议的方法更容易,因为您甚至不需要读取字节。
信用转到:http://prideparrot.com/blog/archive/2012/ 8/uploading_and_returning_files#how_to_return_a_file_as_response
**编辑**
显然我的“答案”与OP的问题相同。但我没有面临他所面临的问题。这可能是旧版本 ASP.NET MVC 的问题?
The absolute easiest way to stream a file into browser using ASP.NET MVC is this:
This is easier than the method suggested by @azarc3 since you don't even need to read the bytes.
Credit goes to: http://prideparrot.com/blog/archive/2012/8/uploading_and_returning_files#how_to_return_a_file_as_response
** Edit **
Apparently my 'answer' is the same as the OP's question. But I am not facing the problem he is having. Probably this was an issue with older version of ASP.NET MVC?
我使用 REST API 在 ASP.NET Core 中对其进行了改编。
I adapted it in ASP.NET Core with REST API.