Skip to content

Commit d6a6aaa

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

11 files changed

+432
-33
lines changed

src/OpenApi/gen/XmlCommentGenerator.Emitter.cs

Lines changed: 41 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,40 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
499505
return Task.CompletedTask;
500506
}
501507
508+
private static IOpenApiParameter? GetOperationParameter(OpenApiOperation operation, ParameterInfo parameterInfo)
509+
{
510+
var parameters = operation.Parameters;
511+
if (parameters is null)
512+
{
513+
return null;
514+
}
515+
516+
var modelNames = parameterInfo
517+
.GetCustomAttributes(inherit: false)
518+
.OfType<IModelNameProvider>()
519+
.Select(p => p.Name)
520+
.Append(parameterInfo.Name)
521+
.Where(n => !string.IsNullOrEmpty(n))
522+
.ToHashSet();
523+
524+
foreach (var parameter in parameters)
525+
{
526+
var parameterName = parameter.Name;
527+
528+
if (string.IsNullOrEmpty(parameterName))
529+
{
530+
continue;
531+
}
532+
533+
if (modelNames.Contains(parameterName))
534+
{
535+
return parameter;
536+
}
537+
}
538+
539+
return null;
540+
}
541+
502542
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter)
503543
{
504544
if (sourceParameter is OpenApiParameterReference parameterReference)

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

Lines changed: 42 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,40 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
481487
return Task.CompletedTask;
482488
}
483489

490+
private static IOpenApiParameter? GetOperationParameter(OpenApiOperation operation, ParameterInfo parameterInfo)
491+
{
492+
var parameters = operation.Parameters;
493+
if (parameters is null)
494+
{
495+
return null;
496+
}
497+
498+
var modelNames = parameterInfo
499+
.GetCustomAttributes(inherit: false)
500+
.OfType<IModelNameProvider>()
501+
.Select(p => p.Name)
502+
.Append(parameterInfo.Name)
503+
.Where(n => !string.IsNullOrEmpty(n))
504+
.ToHashSet();
505+
506+
foreach (var parameter in parameters)
507+
{
508+
var parameterName = parameter.Name;
509+
510+
if (string.IsNullOrEmpty(parameterName))
511+
{
512+
continue;
513+
}
514+
515+
if (modelNames.Contains(parameterName))
516+
{
517+
return parameter;
518+
}
519+
}
520+
521+
return null;
522+
}
523+
484524
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter)
485525
{
486526
if (sourceParameter is OpenApiParameterReference parameterReference)

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

Lines changed: 42 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,40 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
510516
return Task.CompletedTask;
511517
}
512518

519+
private static IOpenApiParameter? GetOperationParameter(OpenApiOperation operation, ParameterInfo parameterInfo)
520+
{
521+
var parameters = operation.Parameters;
522+
if (parameters is null)
523+
{
524+
return null;
525+
}
526+
527+
var modelNames = parameterInfo
528+
.GetCustomAttributes(inherit: false)
529+
.OfType<IModelNameProvider>()
530+
.Select(p => p.Name)
531+
.Append(parameterInfo.Name)
532+
.Where(n => !string.IsNullOrEmpty(n))
533+
.ToHashSet();
534+
535+
foreach (var parameter in parameters)
536+
{
537+
var parameterName = parameter.Name;
538+
539+
if (string.IsNullOrEmpty(parameterName))
540+
{
541+
continue;
542+
}
543+
544+
if (modelNames.Contains(parameterName))
545+
{
546+
return parameter;
547+
}
548+
}
549+
550+
return null;
551+
}
552+
513553
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter)
514554
{
515555
if (sourceParameter is OpenApiParameterReference parameterReference)

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

Lines changed: 42 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,40 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
608614
return Task.CompletedTask;
609615
}
610616

617+
private static IOpenApiParameter? GetOperationParameter(OpenApiOperation operation, ParameterInfo parameterInfo)
618+
{
619+
var parameters = operation.Parameters;
620+
if (parameters is null)
621+
{
622+
return null;
623+
}
624+
625+
var modelNames = parameterInfo
626+
.GetCustomAttributes(inherit: false)
627+
.OfType<IModelNameProvider>()
628+
.Select(p => p.Name)
629+
.Append(parameterInfo.Name)
630+
.Where(n => !string.IsNullOrEmpty(n))
631+
.ToHashSet();
632+
633+
foreach (var parameter in parameters)
634+
{
635+
var parameterName = parameter.Name;
636+
637+
if (string.IsNullOrEmpty(parameterName))
638+
{
639+
continue;
640+
}
641+
642+
if (modelNames.Contains(parameterName))
643+
{
644+
return parameter;
645+
}
646+
}
647+
648+
return null;
649+
}
650+
611651
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter)
612652
{
613653
if (sourceParameter is OpenApiParameterReference parameterReference)

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

Lines changed: 42 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,40 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
482488
return Task.CompletedTask;
483489
}
484490

491+
private static IOpenApiParameter? GetOperationParameter(OpenApiOperation operation, ParameterInfo parameterInfo)
492+
{
493+
var parameters = operation.Parameters;
494+
if (parameters is null)
495+
{
496+
return null;
497+
}
498+
499+
var modelNames = parameterInfo
500+
.GetCustomAttributes(inherit: false)
501+
.OfType<IModelNameProvider>()
502+
.Select(p => p.Name)
503+
.Append(parameterInfo.Name)
504+
.Where(n => !string.IsNullOrEmpty(n))
505+
.ToHashSet();
506+
507+
foreach (var parameter in parameters)
508+
{
509+
var parameterName = parameter.Name;
510+
511+
if (string.IsNullOrEmpty(parameterName))
512+
{
513+
continue;
514+
}
515+
516+
if (modelNames.Contains(parameterName))
517+
{
518+
return parameter;
519+
}
520+
}
521+
522+
return null;
523+
}
524+
485525
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter)
486526
{
487527
if (sourceParameter is OpenApiParameterReference parameterReference)

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

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -490,33 +490,32 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
490490

491491
private static IOpenApiParameter? GetOperationParameter(OpenApiOperation operation, ParameterInfo parameterInfo)
492492
{
493-
if (operation.Parameters is null)
493+
var parameters = operation.Parameters;
494+
if (parameters is null)
494495
{
495496
return null;
496497
}
497498

498-
var names = parameterInfo.GetCustomAttributes(inherit: false)
499+
var modelNames = parameterInfo
500+
.GetCustomAttributes(inherit: false)
499501
.OfType<IModelNameProvider>()
500-
.Select(x => x.Name)
502+
.Select(p => p.Name)
501503
.Append(parameterInfo.Name)
504+
.Where(n => !string.IsNullOrEmpty(n))
502505
.ToHashSet();
503506

504-
foreach (var operationParameter in operation.Parameters)
507+
foreach (var parameter in parameters)
505508
{
506-
// Optimize for the most common case
507-
if (operationParameter.Name == parameterInfo.Name)
509+
var parameterName = parameter.Name;
510+
511+
if (string.IsNullOrEmpty(parameterName))
508512
{
509-
return operationParameter;
513+
continue;
510514
}
511515

512-
// Check all attributes implementing IModelNameProvider for custom names
513-
foreach (var modelNameProvider in parameterInfo.GetCustomAttributes(inherit: false).OfType<IModelNameProvider>())
516+
if (modelNames.Contains(parameterName))
514517
{
515-
var modelName = modelNameProvider.Name;
516-
if (!string.IsNullOrEmpty(modelName) && operationParameter.Name == modelName)
517-
{
518-
return operationParameter;
519-
}
518+
return parameter;
520519
}
521520
}
522521

0 commit comments

Comments
 (0)