Cannot get endpoint metadata from `IApiDescriptionGroupCollectionProvider` which added by `MapXXX().Add(...)`
Is there an existing issue for this?
- [X] I have searched the existing issues
Describe the bug
Program.cs
// ...
app.MapControllers().RequireAuthorization("api_scope");
// ...
WeatherForecastController.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
namespace DemoApp.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly ILogger<WeatherForecastController> _logger;
private readonly IApiDescriptionGroupCollectionProvider _provider;
public WeatherForecastController(ILogger<WeatherForecastController> logger, IApiDescriptionGroupCollectionProvider provider)
{
_logger = logger;
_provider = provider;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
var thisApiDescriptor = _provider.ApiDescriptionGroups.Items.SelectMany(i => i.Items)
.First(x => x.ActionDescriptor.AttributeRouteInfo.Name == "GetWeatherForecast");
var metadata = thisApiDescriptor.ActionDescriptor.EndpointMetadata.OfType<AuthorizeAttribute>()
.ToList();
// metadata is empty
return null;
}
[HttpGet("2", Name = "GetWeatherForecast2")]
[Authorize]
public IEnumerable<WeatherForecast> Get2()
{
var thisApiDescriptor = _provider.ApiDescriptionGroups.Items.SelectMany(i => i.Items)
.First(x => x.ActionDescriptor.AttributeRouteInfo.Name == "GetWeatherForecast2");
var metadata = thisApiDescriptor.ActionDescriptor.EndpointMetadata.OfType<AuthorizeAttribute>()
.ToList();
// metadata is not empty
return null;
}
}
}
Expected Behavior
AuthorizeAttribute should be retived from IApiDescriptionGroupCollectionProvider.Items[x].Items[x].ActionDescriptor.EndpointMetadata;
Steps To Reproduce
No response
Exceptions (if any)
No response
.NET Version
6.0.400-preview.22330.6
Anything else?
No response
@wu-yafeng What are you trying to accomplish by examining the metadata on an action from inside the action method? It'll help triangulate what the best approach here is.
Hi @wu-yafeng. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
@wu-yafeng What are you trying to accomplish by examining the metadata on an action from inside the action method? It'll help triangulate what the best approach here is.
I'm using a swagger authorize operationfilter:
The filter retrive endpoints and attributes on action through IApiDescriptionGroupCollectionProvider.
@wu-yafeng Thanks for clarifying!
Also, aha! I see something that I missed in your code sample. You've noted that when the Authorize attribute is local to the action, then you are able to inspect it in metadata. However, you are not able to observe the metadata that is added via the RequireAuthorization extension method.
The core of this issue is related to the fact that the ApiExplorer APIs are not particularly routing-aware, and as such, they cannot examine any metadata registered on the controller endpoint.
Trying to see if there's a possible workaround here and will update the issue accordingly...
Hi @wu-yafeng. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
@wu-yafeng Thanks for clarifying!
Also, aha! I see something that I missed in your code sample. You've noted that when the
Authorizeattribute is local to the action, then you are able to inspect it in metadata. However, you are not able to observe the metadata that is added via theRequireAuthorizationextension method.The core of this issue is related to the fact that the ApiExplorer APIs are not particularly routing-aware, and as such, they cannot examine any metadata registered on the controller endpoint.
Trying to see if there's a possible workaround here and will update the issue accordingly...
I have an idea: https://github.com/dotnet/aspnetcore/blob/991728c729ab6d67e1eb1b5de4329d116b5a83bb/src/Mvc/Mvc.Core/src/Routing/ActionEndpointFactory.cs#L108
var builder = new RouteEndpointBuilder(requestDelegate, updatedRoutePattern, route.Order)
{
DisplayName = action.DisplayName,
ApplicationServices = _serviceProvider,
Metadata = action.EndpointMetadata
};
assign action.EndpointMetadata to RouteEndpointBuilder.Metadata instead copy each action.EndpointMetadata items to RouteEndpointBuilder.Metadata
Thank you for contacting us. Due to a lack of activity on this discussion issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue.
This issue will be locked after 30 more days of inactivity. If you still wish to discuss this subject after then, please create a new issue!