I'm trying to create a simple nav menu, that automatically populates with links to pages matching a specific query (such as subdirectory or name contains x etc..).
I can get the basic path of every indexed page using:
HashSet<string> pages2 = new HashSet<string>();
foreach (var endpoint in endpointDataSource.Endpoints)
{
foreach (var metadata in endpoint.Metadata)
{
if (metadata is PageRouteMetadata)
{
pages2.Add(((PageRouteMetadata)metadata).PageRoute);
}
}
}
which I got from a similar question here:
EndpointDataSource.Endpoints" outside of the .cshtml document, which seems odd.
As you can see Endpoints
is a type of IReadOnlyList
and it's parent class EndpointDataSource
is a abstruct
class so yes we cannot directly instantiate it but of course we can call it anywhere. Due to its abstruction level
we need to inroduce constructor to invoke it.
Is there a better way to accomplish this?
Yes, we do have the better in fact, eligant way to imvoke it to get the all page name therefore, its meta-data as well. Here is the complete demo for you.
Asp.net core Razor Page For Getting All Containing Page Name:
public class ListAllRazorPagesModel : PageModel
{
private readonly IEnumerable<EndpointDataSource> _endpointSources;
public ListAllRazorPagesModel(IEnumerable<EndpointDataSource> endpointDataSources)
{
_endpointSources = endpointDataSources;
}
public IEnumerable<RouteEndpoint> EndpointSources { get; set; }
public void OnGet()
{
EndpointSources = _endpointSources
.SelectMany(es => es.Endpoints)
.OfType<RouteEndpoint>();
}
}
Note: I have injected EndpointDataSource
using ListAllRazorPagesModel
constructor to invoke Endpoints
over it.
View:
@page
@model ListAllRazorPagesModel
<table >
<thead>
<tr>
<th>Display Name
<th>URL
<th>Route Pattern
</tr>
</thead>
<tbody>
@foreach (var pageName in @Model.EndpointSources)
{
<tr>
<td>@pageName.DisplayName?.TrimStart('/')</td>
<td>@pageName</td>
<td>@pageName.RoutePattern.RawText</td>
</tr>
}
</tbody>
</table>
Output: