dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.43k stars 10.01k forks source link

Description on IBindableFromHttpContext parameter of route handler in Minimal API not generated in OpenAPI requestBody #57685

Open mikekistler opened 2 months ago

mikekistler commented 2 months ago

Is there an existing issue for this?

Describe the bug

In a Minimal API App, the [Description] on an implicit body parameter is lost. In a controller-based app, the description will appear in the description property of the request body in the generated OpenAPI.

Expected Behavior

In a Minimal API app, the Description on an implicit body parameter should appear in the description property of the request body in the generated OpenAPI, just as it does for a controller-based app.

Steps To Reproduce

Add a Description to an implicit body parameter in a minimal API app which is configured to generate its OpenAPI document. Build the project and inspect the operation request body.

Exceptions (if any)

No response

.NET Version

9.0.100-preview.7.24407.12

Anything else?

No response

mikekistler commented 1 month ago

Sorry ... my original bug report was inaccurate. The problem is not with parameters that are explicitly FromBody -- it is with implicit FromBody parameters. I will fix the title & description.

And here is a project that reproduces the issue with preview 7:

https://github.com/mikekistler/aspnet-openapi-samples

Specifically, the XmlBody parameter for this route handler in ``:

    app.MapPost("/xml-body",
    (
        [Description("An Xml request body")] XmlBody body
    ) =>

is rendered in the generated OpenAPI as:

    "requestBody": {
      "content": {
        "application/xml": {
          "schema": {
            "$ref": "#/components/schemas/XmlBody"
          }
        }
      },
      "required": true
    },

By contrast, in the Controllers/RequestBodies/Controlers/RequestBodiesControllers.cs, this route handler:

    public ActionResult<XmlBody> Get(
        [Description("An Xml request body")] XmlBody body  // Implicitly FromBody
    )
    {
        // Return the body as an application/json response.
        return Ok(body);
    }

has this request body in the generated OpenAPI:

    "requestBody": {
      "description": "An Xml request body",
      "content": {
        "application/xml": {
          "schema": {
            "$ref": "#/components/schemas/XmlBody"
          }
        },
        "application/*+xml": {
          "schema": {
            "$ref": "#/components/schemas/XmlBody"
          }
        }
      },
      "required": true
    },
captainsafia commented 1 month ago

So, this bug is specifically related to types that implement some sort of BindAsync method. The EndpointMetadataApiDescriptionProvider currently categorizes any parameters that implement BindAsync as service type parameters:

https://github.com/dotnet/aspnetcore/blob/71f0a94042feed45b4fadb14d5193a08070cca61/src/Mvc/Mvc.ApiExplorer/src/EndpointMetadataApiDescriptionProvider.cs#L277-L287

And doesn't emit ParameterInfo descriptors into the ApiParameterDescription for them. As a result, we don't have any ParameterInfo to query for description attributes and so you don't get any.

I think the right thing to do here is to use the ModelBinding binding source to represent BindAsync types although we'd have to evaluate if anything funky happens if we overload the meaning of ModelBinding meaning MVC's model binding behavior. An alternative would be to define a new BindingSource for BindAsync types but I hesitate to go down this direction...