Skip to content

Commit 16a616e

Browse files
committed
Respect IModelNameProvider when matching OpenAPI parameters
1 parent 2831dc0 commit 16a616e

11 files changed

+369
-25
lines changed

src/OpenApi/gen/XmlCommentGenerator.Emitter.cs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ namespace Microsoft.AspNetCore.OpenApi.Generated
5757
using System.Threading.Tasks;
5858
using Microsoft.AspNetCore.OpenApi;
5959
using Microsoft.AspNetCore.Mvc.Controllers;
60+
using Microsoft.AspNetCore.Mvc.ModelBinding;
6061
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
6162
using Microsoft.Extensions.DependencyInjection;
6263
using Microsoft.OpenApi;
@@ -389,7 +390,12 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
389390
foreach (var parameterComment in methodComment.Parameters)
390391
{
391392
var parameterInfo = methodInfo.GetParameters().SingleOrDefault(info => info.Name == parameterComment.Name);
392-
var operationParameter = operation.Parameters?.SingleOrDefault(parameter => parameter.Name == parameterComment.Name);
393+
if (parameterInfo is null)
394+
{
395+
continue;
396+
}
397+
398+
var operationParameter = GetOperationParameter(operation, parameterInfo);
393399
if (operationParameter is not null)
394400
{
395401
var targetOperationParameter = UnwrapOpenApiParameter(operationParameter);
@@ -499,6 +505,35 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
499505
return Task.CompletedTask;
500506
}
501507
508+
private static IOpenApiParameter? GetOperationParameter(OpenApiOperation operation, ParameterInfo parameterInfo)
509+
{
510+
if (operation.Parameters is null)
511+
{
512+
return null;
513+
}
514+
515+
foreach (var operationParameter in operation.Parameters)
516+
{
517+
// Optimize for the most common case
518+
if (operationParameter.Name == parameterInfo.Name)
519+
{
520+
return operationParameter;
521+
}
522+
523+
// Check all attributes implementing IModelNameProvider for custom names
524+
foreach (var modelNameProvider in parameterInfo.GetCustomAttributes(inherit: false).OfType<IModelNameProvider>())
525+
{
526+
var modelName = modelNameProvider.Name;
527+
if (!string.IsNullOrEmpty(modelName) && operationParameter.Name == modelName)
528+
{
529+
return operationParameter;
530+
}
531+
}
532+
}
533+
534+
return null;
535+
}
536+
502537
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter)
503538
{
504539
if (sourceParameter is OpenApiParameterReference parameterReference)

src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/AddOpenApiTests.CanInterceptAddOpenApi#OpenApiXmlCommentSupport.generated.verified.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//HintName: OpenApiXmlCommentSupport.generated.cs
1+
//HintName: OpenApiXmlCommentSupport.generated.cs
22
//------------------------------------------------------------------------------
33
// <auto-generated>
44
// This code was generated by a tool.
@@ -39,6 +39,7 @@ namespace Microsoft.AspNetCore.OpenApi.Generated
3939
using System.Threading.Tasks;
4040
using Microsoft.AspNetCore.OpenApi;
4141
using Microsoft.AspNetCore.Mvc.Controllers;
42+
using Microsoft.AspNetCore.Mvc.ModelBinding;
4243
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
4344
using Microsoft.Extensions.DependencyInjection;
4445
using Microsoft.OpenApi;
@@ -371,7 +372,12 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
371372
foreach (var parameterComment in methodComment.Parameters)
372373
{
373374
var parameterInfo = methodInfo.GetParameters().SingleOrDefault(info => info.Name == parameterComment.Name);
374-
var operationParameter = operation.Parameters?.SingleOrDefault(parameter => parameter.Name == parameterComment.Name);
375+
if (parameterInfo is null)
376+
{
377+
continue;
378+
}
379+
380+
var operationParameter = GetOperationParameter(operation, parameterInfo);
375381
if (operationParameter is not null)
376382
{
377383
var targetOperationParameter = UnwrapOpenApiParameter(operationParameter);
@@ -481,6 +487,35 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
481487
return Task.CompletedTask;
482488
}
483489

490+
private static IOpenApiParameter? GetOperationParameter(OpenApiOperation operation, ParameterInfo parameterInfo)
491+
{
492+
if (operation.Parameters is null)
493+
{
494+
return null;
495+
}
496+
497+
foreach (var operationParameter in operation.Parameters)
498+
{
499+
// Optimize for the most common case
500+
if (operationParameter.Name == parameterInfo.Name)
501+
{
502+
return operationParameter;
503+
}
504+
505+
// Check all attributes implementing IModelNameProvider for custom names
506+
foreach (var modelNameProvider in parameterInfo.GetCustomAttributes(inherit: false).OfType<IModelNameProvider>())
507+
{
508+
var modelName = modelNameProvider.Name;
509+
if (!string.IsNullOrEmpty(modelName) && operationParameter.Name == modelName)
510+
{
511+
return operationParameter;
512+
}
513+
}
514+
}
515+
516+
return null;
517+
}
518+
484519
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter)
485520
{
486521
if (sourceParameter is OpenApiParameterReference parameterReference)

src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/AdditionalTextsTests.CanHandleXmlForSchemasInAdditionalTexts#OpenApiXmlCommentSupport.generated.verified.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//HintName: OpenApiXmlCommentSupport.generated.cs
1+
//HintName: OpenApiXmlCommentSupport.generated.cs
22
//------------------------------------------------------------------------------
33
// <auto-generated>
44
// This code was generated by a tool.
@@ -39,6 +39,7 @@ namespace Microsoft.AspNetCore.OpenApi.Generated
3939
using System.Threading.Tasks;
4040
using Microsoft.AspNetCore.OpenApi;
4141
using Microsoft.AspNetCore.Mvc.Controllers;
42+
using Microsoft.AspNetCore.Mvc.ModelBinding;
4243
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
4344
using Microsoft.Extensions.DependencyInjection;
4445
using Microsoft.OpenApi;
@@ -400,7 +401,12 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
400401
foreach (var parameterComment in methodComment.Parameters)
401402
{
402403
var parameterInfo = methodInfo.GetParameters().SingleOrDefault(info => info.Name == parameterComment.Name);
403-
var operationParameter = operation.Parameters?.SingleOrDefault(parameter => parameter.Name == parameterComment.Name);
404+
if (parameterInfo is null)
405+
{
406+
continue;
407+
}
408+
409+
var operationParameter = GetOperationParameter(operation, parameterInfo);
404410
if (operationParameter is not null)
405411
{
406412
var targetOperationParameter = UnwrapOpenApiParameter(operationParameter);
@@ -510,6 +516,35 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
510516
return Task.CompletedTask;
511517
}
512518

519+
private static IOpenApiParameter? GetOperationParameter(OpenApiOperation operation, ParameterInfo parameterInfo)
520+
{
521+
if (operation.Parameters is null)
522+
{
523+
return null;
524+
}
525+
526+
foreach (var operationParameter in operation.Parameters)
527+
{
528+
// Optimize for the most common case
529+
if (operationParameter.Name == parameterInfo.Name)
530+
{
531+
return operationParameter;
532+
}
533+
534+
// Check all attributes implementing IModelNameProvider for custom names
535+
foreach (var modelNameProvider in parameterInfo.GetCustomAttributes(inherit: false).OfType<IModelNameProvider>())
536+
{
537+
var modelName = modelNameProvider.Name;
538+
if (!string.IsNullOrEmpty(modelName) && operationParameter.Name == modelName)
539+
{
540+
return operationParameter;
541+
}
542+
}
543+
}
544+
545+
return null;
546+
}
547+
513548
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter)
514549
{
515550
if (sourceParameter is OpenApiParameterReference parameterReference)

src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/CompletenessTests.SupportsAllXmlTagsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//HintName: OpenApiXmlCommentSupport.generated.cs
1+
//HintName: OpenApiXmlCommentSupport.generated.cs
22
//------------------------------------------------------------------------------
33
// <auto-generated>
44
// This code was generated by a tool.
@@ -39,6 +39,7 @@ namespace Microsoft.AspNetCore.OpenApi.Generated
3939
using System.Threading.Tasks;
4040
using Microsoft.AspNetCore.OpenApi;
4141
using Microsoft.AspNetCore.Mvc.Controllers;
42+
using Microsoft.AspNetCore.Mvc.ModelBinding;
4243
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
4344
using Microsoft.Extensions.DependencyInjection;
4445
using Microsoft.OpenApi;
@@ -498,7 +499,12 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
498499
foreach (var parameterComment in methodComment.Parameters)
499500
{
500501
var parameterInfo = methodInfo.GetParameters().SingleOrDefault(info => info.Name == parameterComment.Name);
501-
var operationParameter = operation.Parameters?.SingleOrDefault(parameter => parameter.Name == parameterComment.Name);
502+
if (parameterInfo is null)
503+
{
504+
continue;
505+
}
506+
507+
var operationParameter = GetOperationParameter(operation, parameterInfo);
502508
if (operationParameter is not null)
503509
{
504510
var targetOperationParameter = UnwrapOpenApiParameter(operationParameter);
@@ -608,6 +614,35 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
608614
return Task.CompletedTask;
609615
}
610616

617+
private static IOpenApiParameter? GetOperationParameter(OpenApiOperation operation, ParameterInfo parameterInfo)
618+
{
619+
if (operation.Parameters is null)
620+
{
621+
return null;
622+
}
623+
624+
foreach (var operationParameter in operation.Parameters)
625+
{
626+
// Optimize for the most common case
627+
if (operationParameter.Name == parameterInfo.Name)
628+
{
629+
return operationParameter;
630+
}
631+
632+
// Check all attributes implementing IModelNameProvider for custom names
633+
foreach (var modelNameProvider in parameterInfo.GetCustomAttributes(inherit: false).OfType<IModelNameProvider>())
634+
{
635+
var modelName = modelNameProvider.Name;
636+
if (!string.IsNullOrEmpty(modelName) && operationParameter.Name == modelName)
637+
{
638+
return operationParameter;
639+
}
640+
}
641+
}
642+
643+
return null;
644+
}
645+
611646
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter)
612647
{
613648
if (sourceParameter is OpenApiParameterReference parameterReference)

src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsRouteParametersFromControllers#OpenApiXmlCommentSupport.generated.verified.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//HintName: OpenApiXmlCommentSupport.generated.cs
1+
//HintName: OpenApiXmlCommentSupport.generated.cs
22
//------------------------------------------------------------------------------
33
// <auto-generated>
44
// This code was generated by a tool.
@@ -39,6 +39,7 @@ namespace Microsoft.AspNetCore.OpenApi.Generated
3939
using System.Threading.Tasks;
4040
using Microsoft.AspNetCore.OpenApi;
4141
using Microsoft.AspNetCore.Mvc.Controllers;
42+
using Microsoft.AspNetCore.Mvc.ModelBinding;
4243
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
4344
using Microsoft.Extensions.DependencyInjection;
4445
using Microsoft.OpenApi;
@@ -372,7 +373,12 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
372373
foreach (var parameterComment in methodComment.Parameters)
373374
{
374375
var parameterInfo = methodInfo.GetParameters().SingleOrDefault(info => info.Name == parameterComment.Name);
375-
var operationParameter = operation.Parameters?.SingleOrDefault(parameter => parameter.Name == parameterComment.Name);
376+
if (parameterInfo is null)
377+
{
378+
continue;
379+
}
380+
381+
var operationParameter = GetOperationParameter(operation, parameterInfo);
376382
if (operationParameter is not null)
377383
{
378384
var targetOperationParameter = UnwrapOpenApiParameter(operationParameter);
@@ -482,6 +488,35 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
482488
return Task.CompletedTask;
483489
}
484490

491+
private static IOpenApiParameter? GetOperationParameter(OpenApiOperation operation, ParameterInfo parameterInfo)
492+
{
493+
if (operation.Parameters is null)
494+
{
495+
return null;
496+
}
497+
498+
foreach (var operationParameter in operation.Parameters)
499+
{
500+
// Optimize for the most common case
501+
if (operationParameter.Name == parameterInfo.Name)
502+
{
503+
return operationParameter;
504+
}
505+
506+
// Check all attributes implementing IModelNameProvider for custom names
507+
foreach (var modelNameProvider in parameterInfo.GetCustomAttributes(inherit: false).OfType<IModelNameProvider>())
508+
{
509+
var modelName = modelNameProvider.Name;
510+
if (!string.IsNullOrEmpty(modelName) && operationParameter.Name == modelName)
511+
{
512+
return operationParameter;
513+
}
514+
}
515+
}
516+
517+
return null;
518+
}
519+
485520
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter)
486521
{
487522
if (sourceParameter is OpenApiParameterReference parameterReference)

src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsRouteParametersWithCustomNamesFromControllers#OpenApiXmlCommentSupport.generated.verified.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -495,12 +495,6 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
495495
return null;
496496
}
497497

498-
var names = parameterInfo.GetCustomAttributes(inherit: false)
499-
.OfType<IModelNameProvider>()
500-
.Select(x => x.Name)
501-
.Append(parameterInfo.Name)
502-
.ToHashSet();
503-
504498
foreach (var operationParameter in operation.Parameters)
505499
{
506500
// Optimize for the most common case

src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromControllers#OpenApiXmlCommentSupport.generated.verified.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//HintName: OpenApiXmlCommentSupport.generated.cs
1+
//HintName: OpenApiXmlCommentSupport.generated.cs
22
//------------------------------------------------------------------------------
33
// <auto-generated>
44
// This code was generated by a tool.
@@ -39,6 +39,7 @@ namespace Microsoft.AspNetCore.OpenApi.Generated
3939
using System.Threading.Tasks;
4040
using Microsoft.AspNetCore.OpenApi;
4141
using Microsoft.AspNetCore.Mvc.Controllers;
42+
using Microsoft.AspNetCore.Mvc.ModelBinding;
4243
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
4344
using Microsoft.Extensions.DependencyInjection;
4445
using Microsoft.OpenApi;
@@ -375,7 +376,12 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
375376
foreach (var parameterComment in methodComment.Parameters)
376377
{
377378
var parameterInfo = methodInfo.GetParameters().SingleOrDefault(info => info.Name == parameterComment.Name);
378-
var operationParameter = operation.Parameters?.SingleOrDefault(parameter => parameter.Name == parameterComment.Name);
379+
if (parameterInfo is null)
380+
{
381+
continue;
382+
}
383+
384+
var operationParameter = GetOperationParameter(operation, parameterInfo);
379385
if (operationParameter is not null)
380386
{
381387
var targetOperationParameter = UnwrapOpenApiParameter(operationParameter);
@@ -485,6 +491,35 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
485491
return Task.CompletedTask;
486492
}
487493

494+
private static IOpenApiParameter? GetOperationParameter(OpenApiOperation operation, ParameterInfo parameterInfo)
495+
{
496+
if (operation.Parameters is null)
497+
{
498+
return null;
499+
}
500+
501+
foreach (var operationParameter in operation.Parameters)
502+
{
503+
// Optimize for the most common case
504+
if (operationParameter.Name == parameterInfo.Name)
505+
{
506+
return operationParameter;
507+
}
508+
509+
// Check all attributes implementing IModelNameProvider for custom names
510+
foreach (var modelNameProvider in parameterInfo.GetCustomAttributes(inherit: false).OfType<IModelNameProvider>())
511+
{
512+
var modelName = modelNameProvider.Name;
513+
if (!string.IsNullOrEmpty(modelName) && operationParameter.Name == modelName)
514+
{
515+
return operationParameter;
516+
}
517+
}
518+
}
519+
520+
return null;
521+
}
522+
488523
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter)
489524
{
490525
if (sourceParameter is OpenApiParameterReference parameterReference)

0 commit comments

Comments
 (0)