如何从blazor服务器端下载文件

如何从blazor服务器端下载文件,blazor,blazor-server-side,Blazor,Blazor Server Side,我有一个服务器端blazor应用程序,它可以生成大量数据,当用户单击按钮时,就会使用这些数据生成excel文件。所有这些都很好。但我的问题是,下载内存文件的合适方式是什么?我知道我可以将它保存到web服务器磁盘上,并执行重定向或类似操作来下载它。如果不需要,我宁愿不必将文件保存到磁盘上。我最终使用的解决方案是JS Interop重定向到随后下载的文件 public async Task DownloadFileAsync(string path) { await Js.InvokeAsy

我有一个服务器端blazor应用程序,它可以生成大量数据,当用户单击按钮时,就会使用这些数据生成excel文件。所有这些都很好。但我的问题是,下载内存文件的合适方式是什么?我知道我可以将它保存到web服务器磁盘上,并执行重定向或类似操作来下载它。如果不需要,我宁愿不必将文件保存到磁盘上。

我最终使用的解决方案是JS Interop重定向到随后下载的文件

public async Task DownloadFileAsync(string path)
{
    await Js.InvokeAsync<string>("downloadFile", path);
}

// In JS
function downloadFile(filename) {
    location.href = '/api/downloads/' + filename;
}
公共异步任务下载FileAsync(字符串路径)
{
等待Js.InvokeAsync(“下载文件”,路径);
}
//在JS中
函数下载文件(文件名){
location.href='/api/downloads/'+文件名;
}

您可以这样做

[Route("api/[controller]"]
[ApiController]
public class DownloadController : ControllerBase
{
    [HttpGet, DisableRequestSizeLimit]
    public async Task<IActionResult> Download()
    {
        var memory = new MemoryStream();
        await using(var stream = new FileStream(@"pathToLocalFile", FileMode.Open))
        {
            await stream.CopyToAsync(memory);
        }
        memory.Position = 0;
        //set correct content type here
        return File(memory, "application/octet-stream", "fileNameToBeUsedForSave");
    }
}
[路由(“api/[控制器]”]
[ApiController]
公共类下载控制器:ControllerBase
{
[HttpGet,DisableRequestSizeLimit]
公共异步任务下载()
{
var memory=newmemoryStream();
等待使用(var stream=newfilestream(@“pathToLocalFile”,FileMode.Open))
{
等待流。CopyToAsync(内存);
}
记忆位置=0;
//在此处设置正确的内容类型
返回文件(内存、“应用程序/八位字节流”、“文件名ToBeusedForSave”);
}
}
还有剃刀的一面

<button @onclick="onClick">download</button>

@code {

   private async Task onClick(MouseEventArgs e)
   {
        NavigationManager.NavigateTo("api/download", true);
   }
}
下载
@代码{
专用异步任务onClick(MouseEventArgs e)
{
NavigationManager.NavigateTo(“api/下载”,true);
}
}

此时,您不需要JS重定向:跳过使用MemoryStream可能是一种改进-使用文件流(即流)将文件读入内存,然后将MemoryStream返回0并将其发送到需要流(即文件流)的方法中没有多大意义-只需使用FileStream作为Stream参数来声明文件。如果是500Mb的文件,您将消耗500Mb内存将其加载到MemoryStream中,将256字节数组翻倍N次以读取512Mb,每次翻倍都会复制所有字节,这将耗费大量资源