How to get a list of all routes in ASP.NET Core?
Solution 1
To get at all the routes, you need to use the ApiExplorer part of MVC. You can either mark all your actions with an attribute or use a convention like this one:
public class ApiExplorerVisibilityEnabledConvention : IApplicationModelConvention
{
public void Apply(ApplicationModel application)
{
foreach (var controller in application.Controllers)
{
if (controller.ApiExplorer.IsVisible == null)
{
controller.ApiExplorer.IsVisible = true;
controller.ApiExplorer.GroupName = controller.ControllerName;
}
}
}
}
In Startup.cs, add your new in ConfigureServices(...)
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(
options =>
{
options.Conventions.Add(new ApiExplorerVisibilityEnabledConvention());
options.
}
}
In your ActionFilter
you can then use constructor injection to get the ApiExplorer:
public class MyFilter : ActionFilterAttribute
{
private readonly IApiDescriptionGroupCollectionProvider descriptionProvider;
public MyFilter(IApiDescriptionGroupCollectionProvider descriptionProvider)
{
this.descriptionProvider = descriptionProvider;
}
public override void OnActionExecuting(ActionExecutingContext actionContext)
{
base.OnActionExecuting(actionContext);
// The convention groups all actions for a controller into a description group
var actionGroups = descriptionProvider.ApiDescriptionGroups.Items;
// All the actions in the controller are given by
var apiDescription = actionGroup.First().Items.First();
// A route template for this action is
var routeTemplate = apiDescription.RelativePath
}
}
ApiDescription
, which has the RelativePath
, which is the route template for that route:
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace Microsoft.AspNetCore.Mvc.ApiExplorer
{
public class ApiDescription
{
public string GroupName { get; set; }
public string HttpMethod { get; set; }
public IList<ApiParameterDescription> ParameterDescriptions { get; } = new List<ApiParameterDescription>();
public IDictionary<object, object> Properties { get; } = new Dictionary<object, object>();
public string RelativePath { get; set; }
public ModelMetadata ResponseModelMetadata { get; set; }
public Type ResponseType { get; set; }
public IList<ApiRequestFormat> SupportedRequestFormats { get; } = new List<ApiRequestFormat>();
public IList<ApiResponseFormat> SupportedResponseFormats { get; } = new List<ApiResponseFormat>();
}
}
Solution 2
If you're on ASP.NET Core 3.0+, that means you're using endpoint routing, then you can list all routes with EndpointDataSource
s.
Inject IEnumerable<EndpointDataSource>
to your controller/endpoint then extract anything you need. It works with both controller actions, endpoints, and partially with razor pages (razor pages don't seem to expose available HTTP methods).
[Route("/-/{controller}")]
public class InfoController : Controller
{
private readonly IEnumerable<EndpointDataSource> _endpointSources;
public InfoController(
IEnumerable<EndpointDataSource> endpointSources
)
{
_endpointSources = endpointSources;
}
[HttpGet("endpoints")]
public async Task<ActionResult> ListAllEndpoints()
{
var endpoints = _endpointSources
.SelectMany(es => es.Endpoints)
.OfType<RouteEndpoint>();
var output = endpoints.Select(
e =>
{
var controller = e.Metadata
.OfType<ControllerActionDescriptor>()
.FirstOrDefault();
var action = controller != null
? $"{controller.ControllerName}.{controller.ActionName}"
: null;
var controllerMethod = controller != null
? $"{controller.ControllerTypeInfo.FullName}:{controller.MethodInfo.Name}"
: null;
return new
{
Method = e.Metadata.OfType<HttpMethodMetadata>().FirstOrDefault()?.HttpMethods?[0],
Route = $"/{e.RoutePattern.RawText.TrimStart('/')}",
Action = action,
ControllerMethod = controllerMethod
};
}
);
return Json(output);
}
}
when you visit /-/info/endpoints
, you'll get a list of routes as JSON:
[
{
"method": "GET",
"route": "/-/info/endpoints", // <-- controller action
"action": "Info.ListAllEndpoints",
"controllerMethod": "Playground.Controllers.InfoController:ListAllEndpoints"
},
{
"method": "GET",
"route": "/WeatherForecast", // <-- controller action
"action": "WeatherForecast.Get",
"controllerMethod": "Playground.Controllers.WeatherForecastController:Get"
},
{
"method": "GET",
"route": "/hello", // <-- endpoint route
"action": null,
"controllerMethod": null
},
{
"method": null,
"route": "/about", // <-- razor page
"action": null,
"controllerMethod": null
},
]
Solution 3
You can take a look at this awesome GitHub project:
https://github.com/kobake/AspNetCore.RouteAnalyzer
Readme from the project
=======================
AspNetCore.RouteAnalyzer
View all route information for ASP.NET Core project.
Pickuped screenshot
Usage on your ASP.NET Core project
Install NuGet package
PM> Install-Package AspNetCore.RouteAnalyzer
Edit Startup.cs
Insert code services.AddRouteAnalyzer();
and required using
directive into Startup.cs as follows.
using AspNetCore.RouteAnalyzer; // Add
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddRouteAnalyzer(); // Add
}
Case1: View route information on browser
Insert code routes.MapRouteAnalyzer("/routes");
into Startup.cs as follows.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
....
app.UseMvc(routes =>
{
routes.MapRouteAnalyzer("/routes"); // Add
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
}
Then you can access url of http://..../routes
to view all route informations on your browser. (This url /routes
can be customized by MapRouteAnalyzer()
.)
Case2: Print routes on VS output panel
Insert a code block as below into Startup.cs.
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
IApplicationLifetime applicationLifetime, // Add
IRouteAnalyzer routeAnalyzer // Add
)
{
...
// Add this block
applicationLifetime.ApplicationStarted.Register(() =>
{
var infos = routeAnalyzer.GetAllRouteInformations();
Debug.WriteLine("======== ALL ROUTE INFORMATION ========");
foreach (var info in infos)
{
Debug.WriteLine(info.ToString());
}
Debug.WriteLine("");
Debug.WriteLine("");
});
}
Then you can view all route informations on VS output panel.
Solution 4
Not been successful with the above, as I wanted a full url which I didn't have to mess around with things to construct the url, but instead let the framework handle the resolution. So following on from AspNetCore.RouteAnalyzer
and countless googling and searching, I didn't find a definitive answer.
The following works for me for typical home controller and area controller:
public class RouteInfoController : Controller
{
// for accessing conventional routes...
private readonly IActionDescriptorCollectionProvider _actionDescriptorCollectionProvider;
public RouteInfoController(
IActionDescriptorCollectionProvider actionDescriptorCollectionProvider)
{
_actionDescriptorCollectionProvider = actionDescriptorCollectionProvider;
}
public IActionResult Index()
{
StringBuilder sb = new StringBuilder();
foreach (ActionDescriptor ad in _actionDescriptorCollectionProvider.ActionDescriptors.Items)
{
var action = Url.Action(new UrlActionContext()
{
Action = ad.RouteValues["action"],
Controller = ad.RouteValues["controller"],
Values = ad.RouteValues
});
sb.AppendLine(action).AppendLine().AppendLine();
}
return Ok(sb.ToString());
}
This will output the following in my simple solution:
/
/Home/Error
/RouteInfo
/RouteInfo/Links
/Area51/SecureArea
The above was done using dotnetcore 3 preview but I think it should work with dotnetcore 2.2. Additionally getting the url this way will take into consideration any conventions that have been put in place including the excellent slugify as brought to light on Scott Hanselman's Blog
Solution 5
You can get an HttpRouteCollection from the HttpActionContext via:
actionContext.RequestContext.Configuration.Routes
-- After Question Updated --
The ActionExecutingContext has a RouteData property that it inherits from ControllerContext, which exposes the DataTokens property (which is a route value dictionary). It is probably not the same collection you're used to working with, but it does provide access to that collection:
actionContext.RouteData.DataTokens
clhereistian
Updated on January 16, 2022Comments
-
clhereistian over 2 years
In ASP.NET Core, is there a way to see a list of all the routes defined in Startup? We are using the
MapRoute
extension method ofIRouteBuilder
to define the routes.We are migrating an older project WebAPI project. There we could use
GlobalConfiguration.Configuration.Routes
to get all the routes.More specifically, we are doing this within an action filter.
public class MyFilter : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext actionContext) { base.OnActionExecuting(actionContext); // This no longer works // var allRoutes = GlobalConfiguration.Configuration.Routes; // var allRoutes = ??? } }