[英]Return File from URL as IActionResult
I am attempting to get a PDF to download upon the press of a button using.Net Core and Razor Pages.我正在尝试使用.Net Core和Razor页面按下按钮下载PDF。 This is as close as I've gotten but am encountering the error这与我得到的一样接近,但遇到了错误
"ObjectDisposedException: Cannot access a closed file. System.IO.FileStream.ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)". “ObjectDisposedException:无法访问已关闭的文件。System.IO.FileStream.ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancelToken)”。
How do I properly return the file?如何正确返回文件?
Test.cshtml测试.cshtml
@page
@model LoanCalculator.Pages.TestModel
@{
}
<form method="post">
<fieldset>
<input type="submit" value="Submit" id="submitButton" />
</fieldset>
</form>
Test.cshtml.cs测试.cshtml.cs
namespace LoanCalculator.Pages
{
public class TestModel : PageModel
{
public void OnGet()
{
}
public async Task<IActionResult> OnPostAsync()
{
using var httpClient = new HttpClient();
var url = "https://storage.googleapis.com/a2p-v2-storage/528a02ea-a399-4901-b8d6-d0494be68331";
byte[] imageBytes = await httpClient.GetByteArrayAsync(url);
using var fs = new FileStream("favicon.png", FileMode.Create);
fs.Write(imageBytes, 0, imageBytes.Length);
return File(fs, "application/pdf", "FileDownloadName.png");
}
}
The issue is you are disposing the stream and not setting the position of the stream to zero.问题是您正在处理 stream 而没有将 stream 的 position 设置为零。
You can make this much more memory efficient by just handing the stream off from the request to the response.您只需将 stream 从请求转移到响应,就可以提高 memory 的效率。
Take a look at this example:看看这个例子:
var targetFile = new Uri("https://www.example.com/file.pdf");
var resp = await _httpClientFactory.CreateClient().GetAsync(
targetFile, HttpCompletionOption.ResponseHeadersRead);
Response.ContentLength = resp.Content.Headers.ContentLength;
return File(await resp.Content.ReadAsStreamAsync(),
"application/pdf", Path.GetFileName(targetFile.LocalPath));
(this is not tested and written from memory) (这不是从内存中测试和写入的)
Also, you should be using IHttpClientFactory
and not create a new HttpClient
each time.此外,您应该使用IHttpClientFactory
而不是每次都创建一个新的HttpClient
。
An example of this:一个例子:
// ...
using System.Net.Http;
// ...
namespace LoanCalculator.Pages
{
public class TestModel : PageModel
{
private readonly IHttpClientFactory _httpClientFactory;
public TestModel(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
}
}
In your Startup.cs
, add this:在您的Startup.cs
中,添加以下内容:
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddHttpClient();
// ...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.