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.
2 Answers
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; } 1 Comment
dani herrera
At this time, you don't need JS to redirect: stackoverflow.com/questions/55340677/…
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); } } 3 Comments
Caius Jard
It 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
MarchalPT
The Question is about Blazor Server side not Assembly
Simon Miller
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.