7

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 2

9

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; } 
Sign up to request clarification or add additional context in comments.

1 Comment

At this time, you don't need JS to redirect: stackoverflow.com/questions/55340677/…
1

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

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
The Question is about Blazor Server side not Assembly
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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.