Swashbuckle.WebApi icon indicating copy to clipboard operation
Swashbuckle.WebApi copied to clipboard

Define 'File' Schema Type without filter

Open malichishti opened this issue 7 years ago • 3 comments

Hi,

Is it possible to achieve below without the filter i.e. using an attribute or any other way? image

malichishti avatar Jul 26 '17 07:07 malichishti

Hi,

I have the very same project. Working with ASP.NET Core and Swashbuckle.AspNetCore 1.2.0, the following code does not generate the appropriate "produces", and the "Response Content Type" always shows "application/json" instead of the configured values.

Example of the code:

[HttpPost]
[Produces(@"application/pdf")]
[ProducesResponseType(typeof(FileResult), 200)]
[ProducesResponseType(typeof(void), 400)]
[ProducesResponseType(typeof(void), 401)]
[Route(@"api/[controller]/Report")]
public async Task<IActionResult> GenerateReport([FromBody]Request request)
{
	Stream stream = await GenerateReportAsync(request).ConfigureAwait(false);
	return this.File(stream, @"application/pdf", @"report.pdf");
}

I had to create an IOperationFilter to add it.

Thank you.

rliberoff avatar Feb 26 '18 16:02 rliberoff

Expectations

My expectations would be something like this:

...
[ProducesResponseType(typeof(FileResult), 200)]
[ProducesResponseType(typeof(ErrorModel), 403, MediaTypeNames.Application.Json)]
[ProducesResponseType(typeof(ErrorModel), 404, MediaTypeNames.Application.Json)]
...

The status' code 200 response type would be declared either way:

[Produces(MediaTypeNames.Application.Pdf)] // could act as default, and already does, nice
// or
[ProducesResponseType(typeof(FileResult), 200, MediaTypeNames.Application.Pdf)]

and would produce:

...
"responses": {
  "200": {
    "description": "Success",
    "content": {
      "application/pdf": {
        "schema": {
          "type": "string",
          "format": "binary"
        }
      }
    }
  },
  "403": {
    "description": "Forbidden",
    "content": {
      "application/json": {
        "schema": {
            "$ref": "#/components/schemas/ErrorModel"
        }
      }
    }
  },
  "404": {
    "description": "Not Found",
    "content": {
      "application/json": {
        "schema": {
            "$ref": "#/components/schemas/ErrorModel"
        }
      }
    }
  }
}
...

What changes or should change, imho

In this example, status code 200 stays the same, if you use it with:

[Produces(MediaTypeNames.Application.Pdf)]

But currently if you use:

[ProducesResponseType(typeof(ErrorModel), statusCode, MediaTypeNames.Application.Json)]

or anything defined with content type in ProducesResponseType, you will get just:

"{statusCode}": {
  "description": "{statusCodeDescription}"
}

and the only change would be to add:

"content": {
  "application/json": {
    "schema": {
      "$ref": "#/components/schemas/ErrorModel"
    }
  }
}

if content type is defined.
That is at least the only thing is see wrong here, as @rliberoff already pointed out.

@rliberoff could you post your IOperationFilter, or what did you try to do with it?

BernhardNinaus avatar Feb 18 '22 11:02 BernhardNinaus

Okay, I found a PR on the Swashbuckle.AspNetCore repo which actually implemented this in the SwaggerResponseAttribute https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/1956

However, it is not perfect because [Produces(MediaTypeNames.Application.Pdf)] overrides the more specific SwaggerResponse...

But anyway, could be another issue in the other repo because it is out of scope.
I think this issue can be closed, because the "file" type is not anymore in Open API 3.0 anyway.

I hope, I didn't disturb you all to much, have a nice day.

BernhardNinaus avatar Feb 18 '22 12:02 BernhardNinaus