I have a server side blazor app which builds up a lot of data and when a user clicks a button will use that data to generate an excel file. All of that is working fine. But my question is what is the appropriate way to download that in-memory file? I know I can save it to the web server disk and do a redirect or something like that to download it I would prefer not to have to save the file to disk if I don't have to.
Asked
Active
Viewed 1.6k times
2 Answers
7
The solution I ended up using was JS Interop to redirect to the file which then downloaded it.
public async Task DownloadFileAsync(string path)
{
await Js.InvokeAsync<string>("downloadFile", path);
}
// In JS
function downloadFile(filename) {
location.href = '/api/downloads/' + filename;
}

devlife
- 15,275
- 27
- 77
- 131
-
1At this time, you don't need JS to redirect: https://stackoverflow.com/questions/55340677/how-to-redirect-to-blazor-with-token – dani herrera Nov 25 '19 at 07:48
0
You can do something like this
[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");
}
}
And on a razor side
<button @onclick="onClick">download</button>
@code {
private async Task onClick(MouseEventArgs e)
{
NavigationManager.NavigateTo("api/download", true);
}
}

Martin Ch
- 1,337
- 4
- 21
- 42
-
1It may be an improvement to skip using the MemoryStream - there's not much point using a FileStream (which is a Stream) to read a file into memory then seeking the MemoryStream back to 0 and sending it into a method that needs a Stream (which a FileStream is) - just declare the File using the FileStream for the Stream argument. If it's a 500Mb file you'll burn 500Mb of memory to load it into a MemoryStream and it costs a truckload more resource in doubling a 256 byte array N times to read 512Mb, and copying all the bytes over each time there is a doubling – Caius Jard May 01 '21 at 06:09
-
-
Although this proposed solution tries to address streaming a file, it doesn't account for the question asserting that the file is already in memory (generated). I think @CaiusJard whilst accurate about the usage of memory, got hung up on the details, and missed the simpler point. I believe the proposed solution just misses suggesting you save the file to disk in order to access it from a HTTP request, or else you have to find a way to store the generated file in memory in such a way you can identify it, and access it from a HTTP request. It should also become stale and dispose after time. – Simon Miller Jul 23 '21 at 12:17