domaindrivendev / Swashbuckle.AspNetCore

Swagger tools for documenting API's built on ASP.NET Core
MIT License
5.21k stars 1.3k forks source link

Please support Results<T> as return type of controllers #2595

Open aureole82 opened 1 year ago

aureole82 commented 1 year ago

Introducing .NET 7 Results<T> (https://learn.microsoft.com/en-us/aspnet/core/web-api/action-return-types#resultt-type) Microsoft promised that

All the [ProducesResponseType] attribute's can be excluded, since the HttpResult implementation contributes automatically to the endpoint metadata.

But if I write this:

/// <summary> Request the forecast of a specific day. </summary>
/// <param name="date" example="2023-01-24">Date of the requested forecast. </param>
[HttpGet("{date}", Name = "GetWeatherForecastByDate")]
public Results<Ok<WeatherForecast>, NotFound> Get(DateOnly date)
{
    var forecast = _weatherForecasts.FirstOrDefault(forecast => forecast.Date == date);
    return forecast != null ? TypedResults.Ok(forecast) : TypedResults.NotFound();
}

The generated swagger.json only contains that:

"responses": {
  "200": {
    "description": "Success"
  }
}

In order to get the correct schema I still need to add the following ProducesResponseTypeAttributes :-(

[ProducesResponseType(typeof(WeatherForecast), (int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
hjrb commented 1 year ago

I also need this featue. Thank for your support 👍👍🙏

opflucker commented 1 year ago

I also need this featue. Thank for your support 👍👍🙏

vernou commented 11 months ago

It's a know issue. You can read this GitHub issue to full detail :\ TypedResults metadata are not inferred for API Controllers

In summary, metadata aren't correctly inferred to action that return type HttpResults... but sadly, Swashbuckle need this metadata to generate the OpenApi schema.


While waiting for a resolution, I do a operation filter to generate OpenApi response from HttpResults type and I wrapped it in a NuGet package :\ Vernou.Swashbuckle.HttpResultsAdapter

You can add the package :

dotnet add package Vernou.Swashbuckle.HttpResultsAdapter

So you can register the filter :

var builder = WebApplication.CreateBuilder(args);
...
builder.Services.AddSwaggerGen(options =>
{
    ...
    options.OperationFilter<Vernou.Swashbuckle.HttpResultsAdapter.HttpResultsOperationFilter>();
});

If you prefer, you can just copy/paste the filter file from the package repository :\ HttpResultsOperationFilter.cs

hjrb commented 11 months ago

Hi

It's a know issue. You can read this GitHub issue to full detail : TypedResults metadata are not inferred for API Controllers

In summary, metadata aren't correctly inferred to action that return type HttpResults... but sadly, Swashbuckle need this metadata to generate the OpenApi schema.

While waiting for a resolution, I do a operation filter to generate OpenApi response from HttpResults type and I wrapped it in a NuGet package : Vernou.Swashbuckle.HttpResultsAdapter

You can add the package :

dotnet add package Vernou.Swashbuckle.HttpResultsAdapter

So you can register the filter :

var builder = WebApplication.CreateBuilder(args);
...
builder.Services.AddSwaggerGen(options =>
{
    ...
    options.OperationFilter<Vernou.Swashbuckle.HttpResultsAdapter.HttpResultsOperationFilter>();
});

If you prefer, you can just copy/paste the filter file from the package repository : HttpResultsOperationFilter.cs

Hi, I gave your package a try. But there is one issue: most of my controller methods are async. Hence they return a Task. Your code does not account for this. I'll have a deeper look into your code and send you an suggestion how to hande async

vernou commented 11 months ago

@hjrb, thank for you return.

The support to async action was added in the version 1.0.1.

hjrb commented 11 months ago

excellent

Havunen commented 6 months ago

FYI. this is supported in DotSwashbuckle v3.0.8+

jgarciadelanoceda commented 2 months ago

@martincostello I do not see this an issue, if you use TypeResults you should use them only in MinimalApi (I have checked that the TypedResults works as expected).

I would never use TypedResults over Controllers

vernou commented 2 months ago

From the documentation Controller action return types in ASP.NET Core web API :

Results<TResult1, TResultN> type

The static TypedResults class returns the concrete IResult implementation that allows using IResult as return type. The usage of the concrete IResult implementation offers the following benefit over the IResult type: ...

So it sound a legit use case.

jgarciadelanoceda commented 2 months ago

Yeah, I showed it, but I would in any case create an issue in open-api dotnet and wait for a new release

aureole82 commented 2 months ago

FYI. this is supported in DotSwashbuckle v3.0.8+

I have just tested it with .NET 8 and Swashbuckle.AspNetCore v6.6.2 and it still doesn't produce any response type:

"/WeatherForecast/{date}": {
  "get": {
    "tags": [
      "WeatherForecast"
    ],
    "operationId": "GetWeatherForecastByDate",
    "parameters": [
      {
        "name": "date",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "date"
        }
      }
    ],
    "responses": {
      "200": {
        "description": "OK"
      }
    }
  }
}
jgarciadelanoceda commented 2 months ago

Yeah, I can indeed see the commit that was done in DotnetSwashbuckle, but as is not available either in new openApi package of MS, I have notified them