Skip to content

Commit 67d0c9f

Browse files
authored
Support multiple calls to WithTags in WithOpenApi (#41779)
1 parent b02aab8 commit 67d0c9f

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

src/OpenApi/src/OpenApiGenerator.cs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,23 @@ private static void GenerateDefaultResponses(Dictionary<int, (Type?, MediaTypeCo
328328

329329
private List<OpenApiTag> GetOperationTags(MethodInfo methodInfo, EndpointMetadataCollection metadata)
330330
{
331-
var tags = metadata.GetMetadata<ITagsMetadata>();
331+
var metadataList = metadata.GetOrderedMetadata<ITagsMetadata>();
332+
333+
if (metadataList.Count > 0)
334+
{
335+
var tags = new List<OpenApiTag>();
336+
337+
foreach (var metadataItem in metadataList)
338+
{
339+
foreach (var tag in metadataItem.Tags)
340+
{
341+
tags.Add(new OpenApiTag() { Name = tag });
342+
}
343+
}
344+
345+
return tags;
346+
}
347+
332348
string controllerName;
333349

334350
if (methodInfo.DeclaringType is not null && !TypeHelper.IsCompilerGeneratedType(methodInfo.DeclaringType))
@@ -342,9 +358,7 @@ private List<OpenApiTag> GetOperationTags(MethodInfo methodInfo, EndpointMetadat
342358
controllerName = _environment?.ApplicationName ?? string.Empty;
343359
}
344360

345-
return tags is not null
346-
? tags.Tags.Select(tag => new OpenApiTag() { Name = tag }).ToList()
347-
: new List<OpenApiTag>() { new OpenApiTag() { Name = controllerName } };
361+
return new List<OpenApiTag>() { new OpenApiTag() { Name = controllerName } };
348362
}
349363

350364
private List<OpenApiParameter> GetOpenApiParameters(MethodInfo methodInfo, EndpointMetadataCollection metadata, RoutePattern pattern, bool disableInferredBody)

src/OpenApi/test/OpenApiGeneratorTests.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq.Expressions;
55
using System.Reflection;
66
using System.Security.Claims;
7+
using Microsoft.AspNetCore.Builder;
78
using Microsoft.AspNetCore.Http;
89
using Microsoft.AspNetCore.Http.Metadata;
910
using Microsoft.AspNetCore.Mvc;
@@ -50,6 +51,23 @@ public void UsesApplicationNameAsOperationTagsIfNoDeclaringType()
5051
Assert.Equal(declaringTypeName, tag.Name);
5152
}
5253

54+
[Fact]
55+
public void UsesTagsFromMultipleCallsToWithTags()
56+
{
57+
var testBuilder = new TestEndpointConventionBuilder();
58+
var routeHandlerBuilder = new RouteHandlerBuilder(new[] { testBuilder });
59+
60+
routeHandlerBuilder
61+
.WithTags("A")
62+
.WithTags("B");
63+
64+
var operation = GetOpenApiOperation(() => { }, additionalMetadata: testBuilder.Metadata.ToArray());
65+
66+
Assert.Collection(operation.Tags,
67+
tag => Assert.Equal("A", tag.Name),
68+
tag => Assert.Equal("B", tag.Name));
69+
}
70+
5371
[Fact]
5472
public void ThrowsInvalidOperationExceptionGivenUnnamedParameter()
5573
{
@@ -923,4 +941,17 @@ private struct ArgumentListStruct
923941
public InferredJsonClass FromBody { get; set; }
924942
public HttpContext Context { get; set; }
925943
}
944+
945+
private class TestEndpointConventionBuilder : EndpointBuilder, IEndpointConventionBuilder
946+
{
947+
public void Add(Action<EndpointBuilder> convention)
948+
{
949+
convention(this);
950+
}
951+
952+
public override Endpoint Build()
953+
{
954+
throw new NotImplementedException();
955+
}
956+
}
926957
}

0 commit comments

Comments
 (0)