Reputation: 122
I encountered such a problem. I need to get a list of all url-route from razor pages with value of attribute Authorize Such as
@page "/counter"
@attribute [Authorize("IsAdmin")]
I try to do it by EndpointsDataSource, but not getting the right result
@using Microsoft.AspNetCore.Routing
@using Microsoft.AspNetCore.Mvc.ApplicationModels
@using Microsoft.AspNetCore.Mvc.RazorPages
@using Microsoft.AspNetCore.Http
@using Microsoft.Extensions.DependencyInjection
@using Microsoft.AspNetCore.Mvc.Routing
@inject EndpointDataSource EndpointsDataSource
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Order</th>
<th scope="col">Display Name</th>
<th scope="col">Route Pattern</th>
<th scope="col">Metadata</th>
</tr>
</thead>
<tbody>
@foreach (var endpoint in Endpoints)
{
var routeEndpoint = endpoint as RouteEndpoint;
<tr>
<td>@routeEndpoint?.Order</td>
<td>@endpoint.DisplayName</td>
<td>@routeEndpoint?.RoutePattern.RawText</td>
<td>
<ul>
@foreach (var md in endpoint.Metadata)
{
switch (md)
{
case PageRouteMetadata prm:
<li>
<p>@nameof(PageRouteMetadata)</p>
<ul>
<li>Page Route: @prm.PageRoute</li>
<li>Route Template: @prm.RouteTemplate</li>
</ul>
</li>
break;
case PageActionDescriptor pad:
<li>
<p>@nameof(PageActionDescriptor)</p>
<ul>
<li>Id: @pad.Id</li>
<li>Area: @pad.AreaName</li>
<li>Display Name: @pad.DisplayName</li>
<li>View Engine Path: @pad.ViewEnginePath</li>
<li>Relative Path: @pad.RelativePath</li>
</ul>
</li>
break;
case RouteNameMetadata rnm:
<li>
Route Name Metadata: @rnm.RouteName
</li>
break;
case SuppressLinkGenerationMetadata slg:
<li>
suppress link: @slg.SuppressLinkGeneration;
</li>
break;
default:
<li>@md.ToString()</li>
break;
}
}
</ul>
</td>
</tr>
}
</tbody>
</table>
@code{
public List<Microsoft.AspNetCore.Http.Endpoint> Endpoints { get; set; }
protected override async Task OnInitializedAsync()
{
Endpoints = EndpointsDataSource.Endpoints.ToList();
}
}
But I don’t even get a list of route urls, not to mention the attribute value. Can anyone have any ideas how to do this?
Upvotes: 2
Views: 3817
Reputation: 45764
Replace the code in the Index component with the following code, and add this directive to the FetchData component: @attribute [Authorize]
@page "/"
@using System.Linq;
@using System.Reflection;
<button type="button" @onclick="@GetRouteUrlWithAuthorizeAttribute">Get Route
Url With Authorize Attribute</button>
@code{
private Task GetRouteUrlWithAuthorizeAttribute()
{
// Get all the components whose base class is ComponentBase
var components = Assembly.GetExecutingAssembly()
.ExportedTypes
.Where(t =>
t.IsSubclassOf(typeof(ComponentBase)));
foreach (var component in components)
{
// Print the name (Type) of the Component
Console.WriteLine(component.ToString());
// Now check if this component contains the Authorize attribute
var allAttributes = component.GetCustomAttributes(inherit: true);
var authorizeDataAttributes =
allAttributes.OfType<IAuthorizeData>().ToArray();
// If it does, show this to us...
foreach (var authorizeData in authorizeDataAttributes)
{
Console.WriteLine(authorizeData.ToString());
}
}
return Task.CompletedTask;
}
}
If you're using the default Blazor template, the output should be:
XXX.App
XXX.Shared.MainLayout
XXX.Shared.NavMenu
XXX.Pages.Error
XXX.Pages.FetchData
Microsoft.AspNetCore.Authorization.AuthorizeAttribute
XXX.Pages.Index
Hope this helps...
Upvotes: 3