RicoSuter / NSwag

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

Support for multiple content types for request body #2706

Open Evangelinexx opened 4 years ago

Evangelinexx commented 4 years ago

I have a dotnetcore 3.1 project running which generates MVC controllers based on my documentation.

I also have a request which consumes both application/json and application/x-www-form-urlencoded.

This is my swagger:

  /authentication:
    post:
      operationId: authentication_Authenticate
      summary: Authenticates the user and returns the authentication cookie
      tags:
        - Authentication
      requestBody:
        description: The credentials to be used for authentication
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Credential'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/Credential'
      responses:
        200:
          description: 'Sucessfully authenticated'

Here is the code I needed it to generate:

/// <summary>Authenticates the user and returns the authentication cookie</summary>
/// <param name="body">The credentials to be used for authentication</param>
/// <returns>Sucessfully authenticated</returns>
[Microsoft.AspNetCore.Mvc.HttpPost, Microsoft.AspNetCore.Mvc.Route("authentication")]
[Microsoft.AspNetCore.Mvc.Consumes("application/json")]
public System.Threading.Tasks.Task<UserSession> AuthenticateJson([Microsoft.AspNetCore.Mvc.FromBody] Credential body)
{
    return _implementation.AuthenticateAsync(HttpContext, body);
}

/// <summary>Authenticates the user and returns the authentication cookie</summary>
/// <param name="body">The credentials to be used for authentication</param>
/// <returns>Sucessfully authenticated</returns>
[Microsoft.AspNetCore.Mvc.HttpPost, Microsoft.AspNetCore.Mvc.Route("authentication")]
[Microsoft.AspNetCore.Mvc.Consumes("application/x-www-form-urlencoded")]
public System.Threading.Tasks.Task<UserSession> AuthenticateUrlEncoded([Microsoft.AspNetCore.Mvc.FromForm] Credential body)
{
    return _implementation.AuthenticateAsync(HttpContext, body);
}

In the meantime I have solved it by customising my liquid template, however it would be good to have this solved in general. The nswag generator needs to loop through each content type that the request accepts and generate a new method for each of them.

Worth noting that in my case both methods call the same implementation as they both use the same model, but one pulls it from the body, and the other pulls it from the form. The proper implementation would have a different method for both, as there is no guarantee that the schema will be the same for these.

jimcullenaus commented 4 years ago

+1

This is one of many weird limitations I've seen with NSwag's failure to implement properties set by the OpenAPI specification. Others include responding with appropriate status codes, verifying required properties correctly, and differentiating between the source of an input (e.g. path, header, body).

dgwaldo commented 4 months ago

Anyone know of any client generation tools that support the scenario of multiple content types for the request body?