I have one web API application that has a function that needs to stream some data. Then I have another web application that basically acts like a proxy for that. This other application does a whole lot of other stuff like handling authorization and such. It needs to connect to the API endpoint and pass the stream through potentially doing some addition processing for each row of data. In one case it will need to write out that data into an Excel file, for example.
Unfortunately, I see a lot of tutorials on how to create an IAsyncEnumerable, but not any about actually connecting to an endpoint that exposes one.
Ideally, I would like to actually wrap my IAsyncEnumerable and return it with some other stuff. This is what I basically do with other non-streamed endpoints already:
public class NonStreamedResult : BaseResult
{
public SomeMetaData MetaData {get; set; }
// here Data is usually small, so returning it all at once is no big deal
public IEnumerable<SomeData> Data {get; set; }
}
//....controller
public async Task<NonStreamedResult> GetNonStreamedData()
And on the consuming side, I'm using an HttpClient
, awaiting an HttpResponseMessage
and using ReadAsAsync<T>
to turn that response into an object.
However, if I try to do this:
public class StreamedResult : BaseResult
{
public SomeOtherMetaData MetaData {get; set; }
// Here data could be huge, so we don't want to have to hold it all in memory at once
public IAsyncEnumerable<SomeData> Data {get; set; }
}
//....controller
public async Task<StreamedResult> GetStreamedData()
I will get an error when it tries to deserialize because it doesn't know what concrete class to convert the IAsyncEnumerable
into.
So what's the right way to connect to an endpoint that is using an IAsyncEnumerable
without loading the entire response into memory (obviously) so that I can eventually return another IAsyncEnumerable
from the proxy app?
It would be nice if I could still pass it wrapped, but it's not the end of the world if I have to work with just the naked IAsyncEnumerable
Note that I'm using the Microsoft.Bcl.AsyncInterfaces
NuGet package since I'm still targeting an earlier version of the .NET framework.