Skip to content

Commit 2032c68

Browse files
Populate ActionDescriptor EndpointMetadata
Populate the EndpointMetadata property of the ActionDescriptor on ActionDescriptor instances for minimal actions so that the attributes associated with the request delegate can be inspected. Relates to #34061.
1 parent 1b819d0 commit 2032c68

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

src/Http/Http.Abstractions/src/Routing/EndpointMetadataCollection.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,10 @@ private T[] GetOrderedMetadataSlow<T>() where T : class
151151
/// </summary>
152152
public struct Enumerator : IEnumerator<object?>
153153
{
154+
#pragma warning disable IDE0044
154155
// Intentionally not readonly to prevent defensive struct copies
155156
private object[] _items;
157+
#pragma warning restore IDE0044
156158
private int _index;
157159

158160
internal Enumerator(EndpointMetadataCollection collection)

src/Mvc/Mvc.ApiExplorer/src/EndpointMetadataApiDescriptionProvider.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ private ApiDescription CreateApiDescription(RouteEndpoint routeEndpoint, string
121121
AddSupportedRequestFormats(apiDescription.SupportedRequestFormats, hasJsonBody, routeEndpoint.Metadata);
122122
AddSupportedResponseTypes(apiDescription.SupportedResponseTypes, methodInfo.ReturnType, routeEndpoint.Metadata);
123123

124+
AddActionDescriptorEndpointMetadata(apiDescription.ActionDescriptor, routeEndpoint.Metadata);
125+
124126
return apiDescription;
125127
}
126128

@@ -335,6 +337,31 @@ private static void AddResponseContentTypes(IList<ApiResponseFormat> apiResponse
335337
}
336338
}
337339

340+
private static void AddActionDescriptorEndpointMetadata(
341+
ActionDescriptor actionDescriptor,
342+
EndpointMetadataCollection endpointMetadata)
343+
{
344+
if (endpointMetadata.Count > 0)
345+
{
346+
// ActionDescriptor.EndpointMetadata is an empty array by
347+
// default so need to add the metadata into a new list.
348+
var metadata = new List<object>(endpointMetadata.Count);
349+
350+
foreach (var item in endpointMetadata)
351+
{
352+
if (item is not null)
353+
{
354+
metadata.Add(item);
355+
}
356+
}
357+
358+
if (metadata.Count > 0)
359+
{
360+
actionDescriptor.EndpointMetadata = metadata;
361+
}
362+
}
363+
}
364+
338365
// The CompilerGeneratedAttribute doesn't always get added so we also check if the type name starts with "<"
339366
// For example,w "<>c" is a "declaring" type the C# compiler will generate without the attribute for a top-level lambda
340367
// REVIEW: Is there a better way to do this?

src/Mvc/Mvc.ApiExplorer/test/EndpointMetadataApiDescriptionProviderTest.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Linq;
67
using System.Reflection;
78
using System.Threading;
89
using System.Threading.Tasks;
@@ -310,6 +311,21 @@ public void AddsDisplayNameFromRouteEndpoint()
310311
Assert.Equal("FOO", apiDescription.ActionDescriptor.DisplayName);
311312
}
312313

314+
[Fact]
315+
public void AddsMetadataFromRouteEndpoint()
316+
{
317+
var apiDescription = GetApiDescription([ApiExplorerSettings(IgnoreApi = true)]() => { });
318+
319+
Assert.NotEmpty(apiDescription.ActionDescriptor.EndpointMetadata);
320+
321+
var apiExplorerSettings = apiDescription.ActionDescriptor.EndpointMetadata
322+
.OfType<ApiExplorerSettingsAttribute>()
323+
.FirstOrDefault();
324+
325+
Assert.NotNull(apiExplorerSettings);
326+
Assert.True(apiExplorerSettings.IgnoreApi);
327+
}
328+
313329
private IList<ApiDescription> GetApiDescriptions(
314330
Delegate action,
315331
string pattern = null,
@@ -367,7 +383,7 @@ private class ServiceProviderIsService : IServiceProviderIsService
367383
{
368384
public bool IsService(Type serviceType) => serviceType == typeof(IInferredServiceInterface);
369385
}
370-
386+
371387
private class HostEnvironment : IHostEnvironment
372388
{
373389
public string EnvironmentName { get; set; }

0 commit comments

Comments
 (0)