RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.61k stars 1.22k forks source link

Plaintext parameter/content with uri format causes errors in client code #4903

Open fortender opened 1 month ago

fortender commented 1 month ago

TL;DR I think i found a bug in the c# client code generator that occurs when a string is used with format: uri and causes to use the Uri type but uses new StringContent(string) on request creation.

I was handed an OpenAPI specification that defines endpoints that take plaintext inputs of type string with format uri.

As request body:

      requestBody:
        content:
          text/plain:
            schema:
              type: string
              format: uri

and there's also an endpoint that defines parameters like this:

      parameters:
        - name: url
          in: query
          schema:
            type: string
            format: uri

The C# code generator generates the following client code:

public virtual async System.Threading.Tasks.Task RegisterReceiveCallbackAsync(MessageType? messageType, System.Uri body, System.Threading.CancellationToken cancellationToken)
{
    var client_ = _httpClient;
    var disposeClient_ = false;
    try
    {
        using (var request_ = new System.Net.Http.HttpRequestMessage())
        {
            var content_ = new System.Net.Http.StringContent(body); // Error here
            // ...
        }
        // ...
    }
    // ...
}

This fails of course, as body is neither a string, nor is there a constructor of StringContent that takes an Uri.

The actual problem is caused by the Client.Class.liquid template: https://github.com/RicoSuter/NSwag/blob/b3615b4c4fc23e4b2dc69b8d7d6a420c4931e141/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.liquid#L215-L216

operation.HasPlainTextBodyParameter is true in this case, as the content type is text/plain. But even if you'd set the content type to something that fits to Uri, such as text/uri-list, the generator will serialize it to json, which is not correct anyway.

If we remove format: uri the code generator will use a string rather than an Uri, so we don't run into the problem. But that would also require me to alter the specification file everytime there's an update.

This seems like a bug to me anyway