asp.net-corerazor-pages.net-5

How do you list of all pages in a .NET Razor Pages application?


Is it possible to get a list of all pages in a .NET 5 Razor Pages application?

I have done it in MVC and Blazor before by getting a list of all types in the application and filtering it by their base types (Controller for MVC and ComponentBase for Blazor).

For Razor Pages you could do it by getting all types that implement PageModel, but that doesn't seem to work for pages that do not have a code-behind .cshtml.cs model file.


Solution

  • If you want to list all of the navigable pages, you can use the EndpointDataSource service. You can inject it into your PageModel constructor or directly into a Razor page. The following example returns the relative path of the page files, rooted in the Pages folder. The data is added to a Hashset to prevent duplications. There will be two endpoints for each Index file - one with a route template with /Index on the end and another with an empty string instead of /Index.

    @using Microsoft.AspNetCore.Mvc.RazorPages
    @using Microsoft.AspNetCore.Routing
    @inject EndpointDataSource EndpointsDataSource
    
    @{
        HashSet<string> Pages = new HashSet<string>();
        foreach (var endpoint in EndpointsDataSource.Endpoints)
        {
            foreach(var metadata in endpoint.Metadata)
            {
                if(metadata is PageActionDescriptor)
                {
                    Pages.Add(((PageActionDescriptor)metadata).RelativePath);
                }
            }
        }
    }
    <ul>
        @foreach(var p in Pages)
        {
            <li>@p</li>
        }
    </ul>
    

    If you want to get another property, documentation for the PageActionDescriptor type is here: https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.razorpages.pageactiondescriptor

    Also, if you wanted to get the route templates for each page, filter the metadata for types that are compatible with the PageRouteMetadata type e.g.

    if(metadata is PageRouteMetadata)
    {
        Routes.Add(((PageRouteMetadata)metadata).PageRoute);
    }