Stephen O
Stephen O

Reputation: 101

C# SwaggerGen + AutoRest - How to send a Stream body?

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.

Upvotes: 3

Views: 1327

Answers (1)

Stephen O
Stephen O

Reputation: 101

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

Upvotes: 2

Related Questions