So I built a service that collects information, say, log information, and sends it down to a client. This information is normally streamed right to a web browser via SignalR, but sometimes there is a lot of it, and scrolling through it on the web view can be quite a pain. It would be nice to be able to download the data as a tab-delimited file or something like that, so I can just open it with my favorite text editor and use the search functionality. The service doesn’t persist the data forever, either, so if I want to save the information to look at later, I have to save it somehow.
Since I’m using an Angular SPA, where all server access is via WebAPI. The information doesn’t exist on disk, its all in memory, so you can’t necessarily just open a FileStream and return that.
MemoryStream
To make a stream from stuff you have in memory, you use a MemoryStream. Basically, its just an array of bytes. You can write bytes directly to it with the Write method, or you can use a StreamWriter to make it easier to write basic types:
So you can easily put your data in to a stream, but then you need to return it in the right way from the WebAPI.
FileStreamResult
To return a file stream, you can use a FileStreamResult. This lets you specify the stream, the MIME type, and some other options (like the file name).
The Controller has a shortcut for this – you can just return File:
There’s a couple of “gotchas,” which is why I’m writing this blog post. First, note the lack of a using block around the MemoryStream. This is because the using block will dispose/close the stream, which might be premature (before the file is finished being downloaded). ASP.NET will handle getting rid of this stream for you once the transfer is complete (part of the FileStreamResult), so you don’t need to worry about cleaning it up.
Second, note the Seek method being invoked on the MemoryStream to “rewind” it to the beginning. When you’re writing to a stream, you’re advancing the stream. So, when you’re done writing, you need to effectively rewind the stream to make sure the FileStreamResult is at the beginning to begin the download.
Callback MemoryStream – Darchuk.NET
[…] the last post I talked about streaming data back via a WebAPI. On the front end, I had a “download” […]
ASP.NET CORE WEBAPI文件下载 - CodingNote.cc
[…] https://darchuk.net/2019/05/31/asp-net-core-web-api-returning-a-filestream/ […]
ASP.NET CORE WEBAPI文件下载 – Python量化投资
[…] https://darchuk.net/2019/05/31/asp-net-core-web-api-returning-a-filestream/ […]