当在blazor中将文件从服务器下载到客户端时,似乎还没有一个最佳实践(如果我错了,请纠正我)。一个好的解决方案似乎是实现一个返回文件流的控制器(就像这里所做的:How to download in-memory file from Blazor server-side),还有更多涉及javascript的客户端解决方案(比如:How can one generate and save a file client side using Blazor?)。然而,这些似乎都不完全适合我的问题。
我想要的是一种解决方案,可以让我开始从服务器到客户端的大文件并行下载流。目前,我正在使用一个控制器,它可以从内存中的给定目录中获取文件并将其压缩。我希望用户能够开始从同一页客户端的多个下载流。这目前不适用于我的控制器,因为它重定向用户,用户必须等待下载完成才能开始下一次下载。在blazor中提供并行下载的好方法是什么?
以下是我目前所拥有的(简化版):
控制器:
[ApiController]
[Route("[controller]")]
public class DownloadController : Controller
{
[HttpGet("{directory}/{zipFileName}")]
[DisableRequestSizeLimit]
public IActionResult DownloadZipFile(string directory, string zipFileName)
{
directory = System.Net.WebUtility.UrlDecode(directory);
if (Directory.Exists(directory))
{
using (ZipFile zip = new ZipFile())
{
var files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
foreach (var f in files)
{
zip.AddFile(f,Path.GetDirectoryName(f).Replace(directory, string.Empty));
}
using (MemoryStream memoryStream = new MemoryStream())
{
zip.Save(memoryStream);
return File(memoryStream.ToArray(), "application/zip", String.Format(zipFileName));
}
}
}
else
{
// error handling
}
}
}Razor页面:
<button @onclick="()=>DownloadZip(zipFilePath)">download file</button>
@code {
protected string zipFilePath= @"C:\path\to\files";
protected void DownloadZip(string zipFilePath)
{
NavigationManager.NavigateTo("api/download/" + System.Net.WebUtility.UrlEncode(zipFilePath) + "/ZipFileName.zip", true);
}
}发布于 2021-07-17 08:28:56
不要使用按钮和下载-而是使用带有NavigationManager属性的锚标签:
<a href=@GetZipURL(zipFilePath) target="_new" download>download file</a>@code {
protected string zipFilePath= @"C:\path\to\files";
protected string GetZipURL(string zipFilePath)
{
return $"api/download/{System.Net.WebUtility.UrlEncode(zipFilePath)}/ZipFileName.zip";
}
}你的用户可以随心所欲地向“下载”按钮发送垃圾邮件--浏览器将处理并行下载。
如果你想让它看起来像一个按钮,这只是一点CSS样式。
注意:方法GetZipURL只是返回一个字符串,而不是重定向或导航。
我使用target="_new"来阻止Blazor拦截事件--但从.NET5开始,这不是必需的。
https://stackoverflow.com/questions/68412923
复制相似问题