swagger-api / swagger-codegen

swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
http://swagger.io
Apache License 2.0
16.96k stars 6.04k forks source link

[aspnetcore] Bug generating method in Asp.Net Core 2.2 Controller when action is File Upload (multipart/form-data) (OAS 3) #10137

Open Smootium opened 4 years ago

Smootium commented 4 years ago

Description When trying to describe a File Upload action in OAS 3 YAML using multipart/form-data content (as described in OAS 3.0.1 specs), the generated aspnetcore code contains NO controller method at all. (aspnetcore 2.2)

Swagger-codegen version 3.0.18 (using the "3rd Gen" online generator (https://generator3.swagger.io/index.html))

Declaration File In the RestApi-multipart-formdata.yml, there is one path describing a POST action using the multipart/form-data content.

Options used for generation (note: not including the spec object, for simplicity; see subsequent note in Repro Steps)

{
  "lang": "aspnetcore",
  "specURL": "string",
  "type": "SERVER",
  "codegenVersion": "V3",
  "options": {
    "additionalProperties": {
      "packageName": "Test.Lib",
      "packageVersion": "0.0.1",
      "useDateTimeOffset": true,
      "returnICollection": true,
      "aspnet-core-version": "2.2"
    }
  }
}

Steps to reproduce ❗️ For simplicity sake, I'm listing the easiest way to reproduce the issue. This is not the process we use "in real life" (but the results are the same).

  1. Copy the RestApi-multipart-formdata.yml contents into the online Swagger Editor
  2. Click on Generate Server drop-down menu.
  3. Select aspnetcore.
  4. Open the downloaded generated server content (zip file):

    1. Open the src\IO.Swagger\Controllers folder

    2. Inspect the CalcSessionsApi.cs file. ℹ️ I copied the contents of the CalcSessionsApi.cs file into a gist, for easier inspection.

    3. Notice there is no method generated.

Related issues/PRs I was not able to find any related/similar issues already posted.

Additional Details On a whim, I tried multipart\form-data (instead of multipart/form-data, as it's written in the OAS 3 spec) and at least something gets generated:

public virtual IActionResult CreateCalcSessionFromFile([FromBody]Body body)

Body.cs:

[DataContract]
public partial class Body : IEquatable<Body>
{
   /// <summary>
  /// Gets or Sets TheFile
  /// </summary>
  [Required]
  [DataMember(Name="theFile")]
  public byte[] TheFile { get; set; }

  // remaining contents elided
}

HOWEVER, if the above is an example of what will be produced, then there are additional issues that should be fixed (noted in Requested Fix(es) / Expected Results section).

Requested Fix(es) / Expected Results

  1. The generator should generate a controller method in the ASP.Net Core server code when the correct content-type (of multipart/form-data) is specified in the Swagger declaration file.
  2. When the multipart/form-data schema only declares one File property (using type: string and format: binary or format: base64), the method signature for the generated method should be (or very similar to) what it was in Swagger 2.0 (e.g.)
    public virtual IActionResult CreateCalcSessionFromFile([FromForm][Required()]System.IO.Stream theFile)
    1. Currently, when there is only one 'File' property (type: string and format: binary or format: base64) declared in the multipart/form-data schema, a new model (type) is generated for that property, which is unnecessary complexity and results in an incorrect method signature (the parameter is marked [FromBody] when it should be [FromForm] )
chris-allnutt commented 4 years ago

Not sure if this fixes your issue entirely but the following is of note:

consumes is 2.0, 3.0 defines a requestBody

post:
  requestBody:
    content:
      multipart/form-data:
     .....
Smootium commented 4 years ago

Not sure if this fixes your issue entirely but the following is of note:

consumes is 2.0, 3.0 defines a requestBody

post:
  requestBody:
    content:
      multipart/form-data:
     .....

@chris-allnutt Hi. I was including the Swagger 2 definition in the issue for comparison reasons. However, I think it doesn't add anything to the issue and might be confusing, so I removed it. The YAML I link to in the issue does define the upload according to OAS 3 specs.

djfrmd commented 3 years ago

This seems to affect all AspNetCore versions, not just 2.2.

I am also seeing issues with content type of 'application/x-www-form-urlencoded'

Alexgolshtein commented 2 years ago

It is strange that the problem still exists. I created a support ticket, but there is no hope for a quick fix.