Skip to content

Fix incorrect Swagger return type when using IResult #34197

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

Merged

Conversation

martincostello
Copy link
Member

PR Title

Fix incorrect Swagger return type when using IResult

PR Description

When a POCO is wrapped in an IResult with minimal actions, an incorrect return type is used to determine the default API response format, which results in the response being mapped incorrectly.

This then results in the metadata specified by an [ProducesResponseType] attribute not being used, resulting in the intended response type not being included in the Swagger documentation.

This change resolves this by using apiResponseType instead of responseType on line 268 as it is in the surrounding code:

apiResponseType.ModelMetadata = CreateModelMetadata(apiResponseType.Type);
if (contentTypes.Count > 0)
{
AddResponseContentTypes(apiResponseType.ApiResponseFormats, contentTypes);
}
else if (CreateDefaultApiResponseFormat(responseType) is { } defaultResponseFormat)
{
apiResponseType.ApiResponseFormats.Add(defaultResponseFormat);
}

I discovered this in a sample project that was using the following code where the ProducesStatusCode() extension methods add an ProducesResponseTypeAttribute to the endpoint metadata:

builder.MapGet("/api/items/{id}", async (
    [FromRoute] Guid id,
    ClaimsPrincipal user,
    ITodoService service,
    CancellationToken cancellationToken) =>
{
    var model = await service.GetAsync(user.GetUserId(), id, cancellationToken);
    return model is null ? Results.NotFound() : Results.Json(model);
})
.ProducesStatusCode(StatusCodes.Status200OK, typeof(TodoItemModel))
.ProducesStatusCode(StatusCodes.Status404NotFound)
.RequireAuthorization();

With the fix this results in the following JSON in the Swagger document:

    "/api/items/{id}": {
      "get": {
        "tags": [
          "TodoApp"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TodoItemModel"
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        }
      },
    }

Without the change, the JSON is:

    "/api/items/{id}": {
      "get": {
        "tags": [
          "TodoApp"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
            }
          },
          "404": {
            "description": "Not Found"
          }
        }
      },
    }

When a POCO is wrapped in an IResult, an incorrect return type
is used to determine the default API response format, which results in
the response being mapped correctly. This then results in the metadata
specified by an [ProducesResponseType] attribute not being used.
@ghost ghost added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates community-contribution Indicates that the PR has been added by a community member labels Jul 8, 2021
@pranavkm
Copy link
Contributor

/azp run

@pranavkm pranavkm enabled auto-merge (squash) July 12, 2021 16:48
@pranavkm
Copy link
Contributor

Thanks @martincostello!

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@pranavkm pranavkm added this to the 6.0-preview7 milestone Jul 12, 2021
@davidfowl
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@pranavkm pranavkm merged commit 0590dc7 into dotnet:main Jul 13, 2021
@martincostello martincostello deleted the Minimal-Actions-Fix-Result-Type branch July 13, 2021 19:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants