diff --git a/src/OpenApi/src/OpenApiGenerator.cs b/src/OpenApi/src/OpenApiGenerator.cs index 4936bfba13ce..eb80857184b3 100644 --- a/src/OpenApi/src/OpenApiGenerator.cs +++ b/src/OpenApi/src/OpenApiGenerator.cs @@ -328,7 +328,23 @@ private static void GenerateDefaultResponses(Dictionary GetOperationTags(MethodInfo methodInfo, EndpointMetadataCollection metadata) { - var tags = metadata.GetMetadata(); + var metadataList = metadata.GetOrderedMetadata(); + + if (metadataList.Count > 0) + { + var tags = new List(); + + foreach (var metadataItem in metadataList) + { + foreach (var tag in metadataItem.Tags) + { + tags.Add(new OpenApiTag() { Name = tag }); + } + } + + return tags; + } + string controllerName; if (methodInfo.DeclaringType is not null && !TypeHelper.IsCompilerGeneratedType(methodInfo.DeclaringType)) @@ -342,9 +358,7 @@ private List GetOperationTags(MethodInfo methodInfo, EndpointMetadat controllerName = _environment?.ApplicationName ?? string.Empty; } - return tags is not null - ? tags.Tags.Select(tag => new OpenApiTag() { Name = tag }).ToList() - : new List() { new OpenApiTag() { Name = controllerName } }; + return new List() { new OpenApiTag() { Name = controllerName } }; } private List GetOpenApiParameters(MethodInfo methodInfo, EndpointMetadataCollection metadata, RoutePattern pattern, bool disableInferredBody) diff --git a/src/OpenApi/test/OpenApiGeneratorTests.cs b/src/OpenApi/test/OpenApiGeneratorTests.cs index 1d9b84f359a0..ca88ef7eea50 100644 --- a/src/OpenApi/test/OpenApiGeneratorTests.cs +++ b/src/OpenApi/test/OpenApiGeneratorTests.cs @@ -4,6 +4,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Security.Claims; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.AspNetCore.Mvc; @@ -50,6 +51,23 @@ public void UsesApplicationNameAsOperationTagsIfNoDeclaringType() Assert.Equal(declaringTypeName, tag.Name); } + [Fact] + public void UsesTagsFromMultipleCallsToWithTags() + { + var testBuilder = new TestEndpointConventionBuilder(); + var routeHandlerBuilder = new RouteHandlerBuilder(new[] { testBuilder }); + + routeHandlerBuilder + .WithTags("A") + .WithTags("B"); + + var operation = GetOpenApiOperation(() => { }, additionalMetadata: testBuilder.Metadata.ToArray()); + + Assert.Collection(operation.Tags, + tag => Assert.Equal("A", tag.Name), + tag => Assert.Equal("B", tag.Name)); + } + [Fact] public void ThrowsInvalidOperationExceptionGivenUnnamedParameter() { @@ -923,4 +941,17 @@ private struct ArgumentListStruct public InferredJsonClass FromBody { get; set; } public HttpContext Context { get; set; } } + + private class TestEndpointConventionBuilder : EndpointBuilder, IEndpointConventionBuilder + { + public void Add(Action convention) + { + convention(this); + } + + public override Endpoint Build() + { + throw new NotImplementedException(); + } + } }