Skip to content

Respect IModelNameProvider when matching OpenAPI parameters#64535

Open
khellang wants to merge 14 commits into
dotnet:mainfrom
khellang:fix/openapi-name-provider
Open

Respect IModelNameProvider when matching OpenAPI parameters#64535
khellang wants to merge 14 commits into
dotnet:mainfrom
khellang:fix/openapi-name-provider

Conversation

@khellang

@khellang khellang commented Nov 26, 2025

Copy link
Copy Markdown
Member

Description

This makes sure any attribute implementing IModelNameProvider is respected when matching OpenAPI operation parameters with .NET action parameters.

It also replaces the CancellationToken workaround from the initial review with a proper check against BindingSource.Body, so documentation for parameters that aren't part of the OpenAPI surface (e.g. CancellationToken or [FromServices] parameters) is no longer applied to the request body description.

Fixes #64534
Fixes #64521
Fixes #67076

Copilot AI review requested due to automatic review settings November 26, 2025 08:45
@khellang khellang requested review from a team and captainsafia as code owners November 26, 2025 08:45
@github-actions github-actions Bot added the needs-area-label Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically label Nov 26, 2025
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Nov 26, 2025

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds support for respecting IModelNameProvider attributes (like FromQuery(Name = "...")) when matching OpenAPI operation parameters with .NET action parameters for XML comment documentation. This ensures that XML documentation comments are correctly applied to parameters that have custom names specified via model binding attributes.

Key Changes:

  • Introduces a new GetOperationParameter helper method that considers both the parameter's original name and any custom names from IModelNameProvider attributes
  • Adds early null check for parameterInfo before attempting to match operation parameters
  • Updates generated code across all snapshot test files to include the new logic

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

File Description
src/OpenApi/gen/XmlCommentGenerator.cs Adds System.Reflection using statement for ParameterInfo type
src/OpenApi/gen/XmlCommentGenerator.Emitter.cs Implements the core logic for parameter matching with IModelNameProvider support; adds GetOperationParameter helper method and includes Microsoft.AspNetCore.Mvc.ModelBinding namespace
src/OpenApi/test/.../snapshots/*.verified.cs Updates all snapshot test files to reflect the generated code changes from the source generator

Comment thread src/OpenApi/gen/XmlCommentGenerator.Emitter.cs Outdated
@martincostello martincostello added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates feature-openapi and removed needs-area-label Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically labels Nov 26, 2025
@khellang khellang force-pushed the fix/openapi-name-provider branch 3 times, most recently from 68d5b6f to 16a616e Compare November 26, 2025 09:27
@khellang khellang requested a review from Copilot November 26, 2025 09:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Comment thread src/OpenApi/gen/XmlCommentGenerator.Emitter.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Comment thread src/OpenApi/gen/XmlCommentGenerator.Emitter.cs Outdated
Comment thread src/OpenApi/gen/XmlCommentGenerator.Emitter.cs
Comment thread src/OpenApi/gen/XmlCommentGenerator.Emitter.cs Outdated
var requestBody = operation.RequestBody;
if (requestBody is not null)
{
requestBody.Description = parameterComment.Description;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@captainsafia Do you know why this fallback exists? We're seeing the CancellationToken argument being applied to the request body because of this, which is weird 🤔

@khellang khellang Nov 26, 2025

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a check to skip CancellationToken to avoid applying its XML doc to the request body. I can't see a scenario where you'd ever want to include a cancellation token in your OpenAPI docs 😅

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, instead of checking against typeof(CancellationToken) directly, it should probably check against the binding source to see if it's BindingSource.Body instead of just blindly falling back to setting the request body description.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

@BrennanConroy BrennanConroy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you file a follow-up issue to look at other parameter types besides CancellationToken? e.g. HttpContext, [FromServices], ClaimsPrincipal, etc.

Might want to look at the ApiParameterDescription.BindingSource?

@khellang

khellang commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

Thanks @BrennanConroy! Filed #67076. Can probably take a stab at fixing it as well if no one beats me to it.

@BrennanConroy

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 2 pipeline(s).

@BrennanConroy

Copy link
Copy Markdown
Member

The 2 new tests in src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/OperationTests.Controllers.cs failed. I think the verified file(s) need to be regenerated.

@khellang khellang force-pushed the fix/openapi-name-provider branch from 7e1a640 to d97acbe Compare June 11, 2026 08:08
@khellang

Copy link
Copy Markdown
Member Author

Rebased and updated the stale snapshots. I also included a commit that checks the BindingSource instead of the hard-coded CancellationToken check. It should fix #67076 as well.

{
var parameterInfo = methodInfo.GetParameters().SingleOrDefault(info => info.Name == parameterComment.Name);
var operationParameter = operation.Parameters?.SingleOrDefault(parameter => parameter.Name == parameterComment.Name);
var operationParameter = GetOperationParameter(operation, parameterInfo, parameterComment);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure we care too much, but if it's easy to fix could we avoid calling GetModelNames multiple times per parameter?


foreach (var parameterDescription in context.Description.ParameterDescriptions)
{
if (parameterDescription.Source == BindingSource.Body

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This excludes IFormFile (and other form types) from the description. Should those be excluded?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But those are bound to the body, right?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, so if there is a description on the form param it should end up as the description in openapi?
#67078 calls this out as well.

if (XmlCommentCache.Cache.TryGetValue(DocumentationCommentIdHelper.NormalizeDocId(propertyInfo.CreateDocumentationId()), out var propertyComment))
{
var parameter = operation.Parameters?.SingleOrDefault(p => p.Name == metadata.Name);
var parameter = GetOperationParameter(operation, propertyInfo);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to apply IsRequestBodyParameter to this piece of code as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates community-contribution Indicates that the PR has been added by a community member feature-openapi pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun

Projects

None yet

9 participants