0
votes

I am trying to integrate swagger in Asp.Net core 3.1 Web API using Swashbuckle.AspNetCore (5.5.1) with OAS3. I am having one post method where I need multipart form data (two files and one string value) and for that I have applied below OperationFilter, because I don't want to specify any parameters at action level.

public class ComparePostParamTypes : IOperationFilter
        {
            public void Apply(OpenApiOperation operation, OperationFilterContext context)
            {

                var listOfOutputFormats = new List<string> { "Rtf", "Doc", "DocX", "Pdf" };
                var optionArray = new OpenApiArray();
                optionArray.AddRange(listOfOutputFormats.Select(s => new OpenApiString(s)));
                string documentOutputFormatText =
                    "The format to return";
                switch (operation.OperationId)
                {
                    case "File_Post":
                        operation.Parameters.Clear();
                        operation.Parameters = new List<OpenApiParameter>
                    {
                        new OpenApiParameter
                        {
                            Name = "file1", In = ParameterLocation.Query,
                            Required = true,
                            Description = "First Document",
                            Schema = new OpenApiSchema()
                            {
                                Type="string",
                                Format="binary"
                            }
                        },
                        new OpenApiParameter
                        {
                            Name = "file2", In = ParameterLocation.Query,
                            Required = true,
                            Description = "Second Document",
                            Schema = new OpenApiSchema()
                            {
                                Type="string",
                                Format="binary"
                            }
                        },
                        new OpenApiParameter
                        {Name = "outputFormat", In = ParameterLocation.Query, Description = documentOutputFormatText,
                            Schema = new OpenApiSchema()
                            {
                                Type="string",
                                Enum = optionArray,
                                Default =  new OpenApiString("Rtf"),
                            }
                        }
                    };
                        break;

                }
            }

        }

This is my controller endpoint

        /// <summary>
        /// POSTing two documents as a multipart/form-data.
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns>The result in the specified format (see outputFormat parameter)</returns>
        /// <remarks>
        /// Pass two document and output format</remarks>
        /// <response code="200">OK</response>
        /// <response code="500">Internal error</response>
        /// <response code="403">Forbidden</response>
        /// <response code="422">UnprocessableEntity</response>
        /// <response code="503">ServiceUnavailable</response>
        /// <response code="400">BadRequest</response>
        [Produces("application/pdf", "application/msword", "application/zip")]
        [Consumes("multipart/form-data")]
        [ProducesResponseType(StatusCodes.Status200OK, Type = null)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError, Type = null)]
        [ProducesResponseType(StatusCodes.Status403Forbidden, Type = null)]
        [ProducesResponseType(StatusCodes.Status422UnprocessableEntity, Type = null)]
        [ProducesResponseType(StatusCodes.Status503ServiceUnavailable, Type = null)]
        [ProducesResponseType(StatusCodes.Status400BadRequest, Type = null)]
        [HttpPost(Name ="File_Post")]
        public IActionResult Post()
        {
            var builBoundary  = Request.GetMultipartBoundary();
            return Ok(builBoundary);
        }

Correct Swagger UI is rendered

Swagger UI

But when I clicked on execute button after attaching files nothing happened.

This is generated swagger JSON

{
  "openapi": "3.0.1",
  "info": {
    "title": "Demo",
    "version": "v1"
  },
  "paths": {
    "/File": {
      "post": {
        "tags": [
          "File"
        ],
        "summary": "POSTing two documents as a multipart/form-data.",
        "description": "Pass two document and output format",
        "operationId": "File_Post",
        "parameters": [
          {
            "name": "file1",
            "in": "query",
            "description": "First Document",
            "required": true,
            "schema": {
              "type": "string",
              "format": "binary"
            }
          },
          {
            "name": "file2",
            "in": "query",
            "description": "Second Document",
            "required": true,
            "schema": {
              "type": "string",
              "format": "binary"
            }
          },
          {
            "name": "outputFormat",
            "in": "query",
            "description": "The format to return",
            "schema": {
              "enum": [
                "Rtf",
                "Doc",
                "DocX",
                "Pdf"
              ],
              "type": "string",
              "default": "Rtf"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "500": {
            "description": "Internal error"
          },
          "403": {
            "description": "Forbidden"
          },
          "422": {
            "description": "UnprocessableEntity"
          },
          "503": {
            "description": "ServiceUnavailable"
          },
          "400": {
            "description": "BadRequest"
          }
        }
      }
    }
  },
  "components": { }
}

Please tell me what should I do to fix this.

1

1 Answers

0
votes

I am able to fix this by updating OperationFilter

public class ComparePostParamTypes : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var listOfOutputFormats = new List<string> { "Rtf", "Doc", "DocX", "Pdf" };
        var optionArray = new OpenApiArray();
        optionArray.AddRange(listOfOutputFormats.Select(s => new OpenApiString(s)));
        string documentOutputFormatText =
            "The format to return";
        switch (operation.OperationId)
        {
            case "File_Post":
                var multipartBodyPost = new OpenApiMediaType
                {
                    Schema = new OpenApiSchema
                    {
                        Type = "object",
                        Properties =
                        {
                            ["file1"] = new OpenApiSchema
                            {
                                Description = "First Document",
                                Type = "string",
                                Format = "binary"
                            },
                            ["file2"] = new OpenApiSchema
                            {
                                Description = "Second Document",
                                Type = "string",
                                Format = "binary"
                            },
                            ["outputFormat"] = new OpenApiSchema
                            {
                                Description = documentOutputFormatText,
                                Type = "string",
                                Enum = optionArray,
                                Default =  new OpenApiString("Rtf"),
                            },
                        },
                        Required = { "file1", "file2" }
                    }
                };

                operation.RequestBody = new OpenApiRequestBody
                {
                    Content =
                    {
                        ["multipart/form-data"] = multipartBodyPost
                    }
                };
               
                break;
        }
    }

}

I more details, check this link https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1782