Skip to content

Commit 3accbd6

Browse files
Populate ActionDescriptor EndpointMetadata (#34065)
* 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. * Simplify metadata assignment Remove filtering and just directly populate the list. Fix typo in comment.
1 parent 794a2a8 commit 3accbd6

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

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

Lines changed: 3 additions & 1 deletion
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
155-
private readonly object[] _items;
156+
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: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ private ApiDescription CreateApiDescription(RouteEndpoint routeEndpoint, string
122122
AddSupportedRequestFormats(apiDescription.SupportedRequestFormats, hasJsonBody, routeEndpoint.Metadata);
123123
AddSupportedResponseTypes(apiDescription.SupportedResponseTypes, methodInfo.ReturnType, routeEndpoint.Metadata);
124124

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

@@ -339,8 +341,20 @@ private static void AddResponseContentTypes(IList<ApiResponseFormat> apiResponse
339341
}
340342
}
341343

344+
private static void AddActionDescriptorEndpointMetadata(
345+
ActionDescriptor actionDescriptor,
346+
EndpointMetadataCollection endpointMetadata)
347+
{
348+
if (endpointMetadata.Count > 0)
349+
{
350+
// ActionDescriptor.EndpointMetadata is an empty array by
351+
// default so need to add the metadata into a new list.
352+
actionDescriptor.EndpointMetadata = new List<object>(endpointMetadata);
353+
}
354+
}
355+
342356
// The CompilerGeneratedAttribute doesn't always get added so we also check if the type name starts with "<"
343-
// For example,w "<>c" is a "declaring" type the C# compiler will generate without the attribute for a top-level lambda
357+
// For example, "<>c" is a "declaring" type the C# compiler will generate without the attribute for a top-level lambda
344358
// REVIEW: Is there a better way to do this?
345359
private static bool IsCompilerGenerated(Type type) =>
346360
Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute)) || type.Name.StartsWith('<');

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.Security.Claims;
89
using System.Threading;
@@ -342,6 +343,21 @@ public void AddsDisplayNameFromRouteEndpoint()
342343
Assert.Equal("FOO", apiDescription.ActionDescriptor.DisplayName);
343344
}
344345

346+
[Fact]
347+
public void AddsMetadataFromRouteEndpoint()
348+
{
349+
var apiDescription = GetApiDescription([ApiExplorerSettings(IgnoreApi = true)]() => { });
350+
351+
Assert.NotEmpty(apiDescription.ActionDescriptor.EndpointMetadata);
352+
353+
var apiExplorerSettings = apiDescription.ActionDescriptor.EndpointMetadata
354+
.OfType<ApiExplorerSettingsAttribute>()
355+
.FirstOrDefault();
356+
357+
Assert.NotNull(apiExplorerSettings);
358+
Assert.True(apiExplorerSettings.IgnoreApi);
359+
}
360+
345361
private IList<ApiDescription> GetApiDescriptions(
346362
Delegate action,
347363
string pattern = null,
@@ -399,7 +415,7 @@ private class ServiceProviderIsService : IServiceProviderIsService
399415
{
400416
public bool IsService(Type serviceType) => serviceType == typeof(IInferredServiceInterface);
401417
}
402-
418+
403419
private class HostEnvironment : IHostEnvironment
404420
{
405421
public string EnvironmentName { get; set; }

0 commit comments

Comments
 (0)