-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
There is an issue with the generation of OpenAPI documentation when using the [FromQuery] attribute inside a separate class. The expected behavior is that when parameters are directly specified in the action method using [FromQuery], the OpenAPI documentation is generated correctly, including the associated descriptions. However, when the [FromQuery] attributes are moved into a separate class (in this case, QueryDto), the descriptions are not recognized in the generated OpenAPI documentation.
Example: Failing Case (Using a Separate DTO Class)
[HttpGet]
public Task<IActionResult> GetWithQueryDto([FromQuery] QueryDto query)
{
return Task.FromResult<IActionResult>(Ok());
}
public record QueryDto
{
[Description("Page index")]
[FromQuery(Name = "p")]
public int Page { get; init; }
[Description("Page size")]
[FromQuery(Name = "s")]
public int Size { get; init; }
[Description("Sort by")]
[FromQuery(Name = "sort")]
public string SortBy { get; init; }
}
In this case, the descriptions for the QueryDto properties are not reflected in the generated OpenAPI documentation.
"/WeatherForecast/GetWithQueryDto": {
"get": {
"tags": [
"WeatherForecast"
],
"parameters": [
{
"name": "p",
"in": "query",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"name": "s",
"in": "query",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"name": "sort",
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
}
Expected Behavior
Example: Working Case (Inline Parameters)
[HttpGet]
public Task<IActionResult> GetInline(
[Description("Page index")] [FromQuery(Name = "p")]
int page,
[Description("Page size")] [FromQuery(Name = "s")]
int size,
[Description("Sort by")] [FromQuery(Name = "sort")]
string sortBy
)
{
return Task.FromResult<IActionResult>(Ok());
}
In this case, the OpenAPI documentation is generated correctly, including the descriptions for each query parameter.
"/WeatherForecast/GetInline": {
"get": {
"tags": [
"WeatherForecast"
],
"parameters": [
{
"name": "p",
"in": "query",
"description": "Page index",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"name": "s",
"in": "query",
"description": "Page size",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"name": "sort",
"in": "query",
"description": "Sort by",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
},
Steps To Reproduce
I have created a minimal demo that can be reproduced. The address is as follows: OpenapiDemo
Exceptions (if any)
No response
.NET Version
9.0.200
Anything else?
Microsoft.AspNetCore.OpenApi: 9.0.3
.NET SDK:
Version: 9.0.200
Commit: 90e8b202f2
Workload version: 9.0.200-manifests.69179adf
MSBuild version: 17.13.8+cbc39bea8
Runtime Environment:
OS Name: Windows
OS Version: 10.0.26100
OS Platform: Windows
RID: win-x64
Base Path: E:\dotnet\sdk\9.0.200\
.NET workloads installed:
[android]
Installation Source: SDK 9.0.200, VS 17.14.35821.62
Manifest Version: 35.0.39/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.sdk.android\35.0.39\WorkloadManifest.json
Install Type: Msi
[ios]
Installation Source: SDK 9.0.200, VS 17.14.35821.62
Manifest Version: 18.2.9180/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.sdk.ios\18.2.9180\WorkloadManifest.json
Install Type: Msi
[maccatalyst]
Installation Source: SDK 9.0.200, VS 17.14.35821.62
Manifest Version: 18.2.9180/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.sdk.maccatalyst\18.2.9180\WorkloadManifest.json
Install Type: Msi
[maui-windows]
Installation Source: SDK 9.0.200, VS 17.14.35821.62
Manifest Version: 9.0.14/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.sdk.maui\9.0.14\WorkloadManifest.json
Install Type: Msi
Configured to use loose manifests when installing new manifests.
Host:
Version: 9.0.2
Architecture: x64
Commit: 80aa709f5d
.NET SDKs installed:
6.0.404 [E:\dotnet\sdk]
8.0.100-preview.5.23303.2 [E:\dotnet\sdk]
9.0.200 [E:\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 3.1.23 [E:\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.12 [E:\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.0-preview.5.23302.2 [E:\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.13 [E:\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.2 [E:\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.23 [E:\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.17 [E:\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.12 [E:\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.0-preview.5.23280.8 [E:\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.7 [E:\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.13 [E:\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.2 [E:\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.12 [E:\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.0-preview.5.23302.2 [E:\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.13 [E:\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 9.0.2 [E:\dotnet\shared\Microsoft.WindowsDesktop.App]
Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]
Environment variables:
Not set
global.json file:
Not found
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download