Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
aureole82 opened this issue Jan 24, 2023 · 14 comments
Open

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

aureole82 opened this issue Jan 24, 2023 · 14 comments
Labels
help-wanted A change up for grabs for contributions from the community

Comments

@aureole82
Copy link

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
Copy link

hjrb commented Feb 2, 2023

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

1 similar comment
@opflucker
Copy link

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

@vernou
Copy link

vernou commented Oct 4, 2023

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
Copy link

hjrb commented Oct 5, 2023

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
Copy link

vernou commented Oct 8, 2023

@hjrb, thank for you return.

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

@hjrb
Copy link

hjrb commented Oct 9, 2023

excellent

@Havunen
Copy link

Havunen commented Feb 26, 2024

FYI. this is supported in DotSwashbuckle v3.0.8+

@martincostello martincostello added the help-wanted A change up for grabs for contributions from the community label Apr 14, 2024
@jgarciadelanoceda
Copy link
Contributor

jgarciadelanoceda commented Jul 12, 2024

@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
Copy link

vernou commented Jul 12, 2024

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
Copy link
Contributor

jgarciadelanoceda commented Jul 12, 2024

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

@aureole82
Copy link
Author

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
Copy link
Contributor

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

sergeevgk added a commit to sergeevgk/weather-forecasting that referenced this issue Jul 26, 2024
…th FluentValidator. 2. Change actions return type to TypedResults to return different responses. Still have to use ProducesResponseType for Swagger. See domaindrivendev/Swashbuckle.AspNetCore#2595
@jgarciadelanoceda
Copy link
Contributor

@martincostello I am thinking about applying the same fix that was done in DotSwashbuckle. I created a PR to fix this on aspnetCore itself but I am not sure if they are going to backport it.
dotnet/aspnetcore#57464

@martincostello
Copy link
Collaborator

I think it's fair game for any changes in DotSwashbuckle to fix user's issues to be ported back here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help-wanted A change up for grabs for contributions from the community
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants