3

I imagine this is a pretty typical scenario: Our solution exposes an API constructed from asp core C# controllers, from which we generate a swagger.json (Using https://github.com/domaindrivendev/Swashbuckle.AspNetCore).

We call this api in code through a C# client we've generated using AutoRest (https://github.com/Azure/autorest).

To perform a potentially large upload, we'd like to use our AutoRest generated client to pass a Stream from a C# caller to our back-end, to avoid having to serialise / deserialise a complete object.

I can't work out how I might use the two tools together to pass a Stream in with a call from our c# code. I've tried adding it as a parameter, but this results in AutoRest creating a "Stream" model for System.IO.Stream, which is then used as the type of the input parameter instead of it just keeping the original type. I've tried passing it in as a [FromBody] parameter, but in addition to the issue above, AutoRest then also types it as StringContent before adding it to the request instead StreamContent (Likely because SwaggerGen doesn't identify it as a Stream?).

Would appreciate any advice - But if we can't do this we can always use a HTTPClient manually, I guess.

Stephen O
  • 91
  • 8

1 Answers1

2

We were unable to solve this and ended up with a less than ideal solution that was still (To us) preferable to using a manually generated HTTPClient.

  • Our Swagger model does not take in a Stream (We still make use of a Stream, we just get it directly from the AspNetCore Request inside our controller. We have a custom validator which ensures the stream is present and has a non-zero length)
  • We created a partial class to go alongside our automatically generated api client
  • We took the method which needed to accept a stream and copied it verbatim from the automatically generated api client, and placed it in our new partial class
  • We modified the automatically generated code's method to take in a Stream
  • We modified the automatically generated code with the following addition:

            // BEGIN MANUALLY MODIFIED CODE
        _httpRequest.Content = new StreamContent(inputStream);
        // ensure that Expect Continue behaviour is always used for binary submissions
        _httpRequest.Headers.ExpectContinue = true;
        // END MANUALLY MODIFIED CODE 
    

Now we just use this manually generated method for all calls to that endpoint instead of the automatically generated method. This comes with a couple of significant caveats:

  • If the Swagger model changes, we need to update the manually generated method manually
  • Anyone mocking the system needs to know that our code uses the method which accepts the stream, not the automatically generated method
Stephen O
  • 91
  • 8
  • 1
    This is a pretty old question, but did you ever manage to get this working "properly" please? – rumblefx0 Jan 12 '21 at 12:31
  • @rumblefx0 - I'm not on this project anymore, but I've just taken a quick look at the publicly hosted repo for it and the hack is still there. There's a note to revisit the hack for Swagger 3.0. – Stephen O Jan 14 '21 at 08:09
  • Thnx for the answer, we'll figure something out... :) – rumblefx0 Jan 15 '21 at 10:24