2

I have several route templates like below and a lot of controllers which include several endpoints.

Project\App_Start\WebApiConfig.cs:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Code omission

        config.Routes.MapHttpRoute(
            name: "Template 1",
            routeTemplate: "api/{controller}/{id}/action"
        );
        config.Routes.MapHttpRoute(
            name: "Template 2",
            routeTemplate: "api/master/{controller}/{id}/{history}",
            defaults: new { id = RouteParameter.Optional, history = RouteParameter.Optional }
        );
        config.Routes.MapHttpRoute(
            name: "Default template",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

How can I get a list of all the routes (endpoints) depending on existing Controllers and their methods?


I'm expecting to get something like:

GET: api/xxx/
PUT: api/xxx/{id}
DELETE: api/xxx/{id}
PUT: api/yyy/{id}

and so on.


Update #1

I tried Charles' advice, but seems it shows only route templates Charles' advice


Update #2

I tried this advice.

diff --git a/Project/App_Start/WebApiConfig.cs b/Project/App_Start/WebApiConfig.cs
index 9b5a05e..6eb376f 100755
--- a/Project/App_Start/WebApiConfig.cs
+++ b/Project/App_Start/WebApiConfig.cs
@@ -1,15 +1,33 @@
 namespace Project
 {
+    public class ObservableDirectRouteProvider : IDirectRouteProvider
+    {
+        public IReadOnlyList<RouteEntry> DirectRoutes { get; private set; }
+
+        public IReadOnlyList<RouteEntry> GetDirectRoutes(HttpControllerDescriptor controllerDescriptor, IReadOnlyList<HttpActionDescriptor> actionDescriptors, IInlineConstraintResolver constraintResolver)
+        {
+            var defaultDirectRouteProvider = new DefaultDirectRouteProvider();
+            var directRoutes = defaultDirectRouteProvider.GetDirectRoutes(controllerDescriptor, actionDescriptors, constraintResolver);
+            DirectRoutes = DirectRoutes?.Union(directRoutes).ToList() ?? directRoutes;
+            return directRoutes;
+        }
+    }
+
     /// <summary>
     /// コンフィグクラス
     /// </summary>
     public static class WebApiConfig
     {
+        public static ObservableDirectRouteProvider GlobalObservableDirectRouteProvider = new ObservableDirectRouteProvider();

         /// <summary>
         /// コンフィグ登録
@@ -26,7 +44,7 @@ namespace Project
             config.EnableCors(cors);

-            config.MapHttpAttributeRoutes();
+            config.MapHttpAttributeRoutes(GlobalObservableDirectRouteProvider)

diff --git a/Project/Global.asax.cs b/Project/Global.asax.cs
index 12bab21..afa6c5d 100644
--- a/Project/Global.asax.cs
+++ b/Project/Global.asax.cs
@@ -24,6 +25,11 @@ namespace Project
         protected void Application_Start()
         {
             GlobalConfiguration.Configure(WebApiConfig.Register);
+            var registeredRouteList = WebApiConfig.GlobalObservableDirectRouteProvider.DirectRoutes;
+            for (int i = 0; i < registeredRouteList.Count; i++)
+            {
+                System.Diagnostics.Debug.WriteLine(registeredRouteList[i].Route.RouteTemplate);
+            }
         }

I was able to get list of endpoints, but that list don't include all endpoints.
As I understand that list include endpoints, where there is explicit route attribute, for example:

[RoutePrefix("api/xxx")]
public class XXXController : ApiController
// OR
[HttpGet]
[Route("{Id}/history")]
public HttpResponseMessage Get([FromUri] int id)

But endpoints without attached RoutePrefix or Route has not included to the list.

Yeheshuah
  • 1,216
  • 1
  • 13
  • 28
  • Maybe this will help? https://stackoverflow.com/questions/28435734/get-list-of-all-routes – SᴇM Nov 21 '19 at 06:30
  • SeM, there is about ASP.NET Core. Does it appropriate to ASP.NET? – Yeheshuah Nov 21 '19 at 06:31
  • tymtam, I'm sorry there is about ASP.NET Core. Does it appropriate to ASP.NET? – Yeheshuah Nov 21 '19 at 06:38
  • As i already got downvoted i won't bother posting all the code anymore. But if you want a complete URL map with all the endpoints you have to loop over all methods of all controllers, fetch all methods of type ActionResult and Task then use GetCustomAttribute on all the methods to get the HttpMethod. Use UrlHelper.GenerateUrl to get the Url for each action. – Charles Nov 21 '19 at 07:33
  • Searching on duckduckgo with the exact wording of your title yields multiple results. Did you not attempt to search before asking? – Joelius Nov 21 '19 at 08:30
  • Joelius, of course, first of all I tried to search. – Yeheshuah Nov 21 '19 at 09:31

3 Answers3

0

I didn't find the way to get list of all routes (ASP.NET) when RoutePrefix or Route attributes are not using, but following solution has helped me.
※ I think it's impossible to get proper list of all routes when RoutePrefix or Route attributes are not using.

  1. Install Microsoft.AspNet.WebApi.HelpPage package.
    Tools → NuGet Package Manager → Package Manager Console
    PW> Install-Package Microsoft.AspNet.WebApi.HelpPage
    
  2. Edit Application_Start method of XXXProject\Global.asax.cs as follow.
    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);
        AreaRegistration.RegisterAllAreas(); // ★Add this line
    }
    
  3. Edit Register method of XXXProject\Areas\HelpPage\App_Start\HelpPageConfig.cs as follow.
    public static void Register(HttpConfiguration config)
    {
        // Uncomment the following to use the documentation from XML documentation file.
        config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml"))); // ★Uncomment this line
    }
    
  4. Enable the XML documentation file.
    Solution explorer → Right click on Project → Select Properties → Select Build page
    Input "App_Data/XmlDocument.xml" in textfield. XML documentation

Attributes you should use to get proper ASP.NET Web API's help pages.

  1. ResponseType
    [ResponseType(typeof(MyObject))]
    public HttpResponseMessage GetMyObject()
    
  2. RoutePrefix and Route
    [RoutePrefix("api/MyController")]
    public class MyController : ApiController
    
    [Route("MyObject")]
    public HttpResponseMessage GetMyObject()
    
  3. FromUri and FromBody (optional)
    public HttpResponseMessage PutMyObject([FromUri] int id, [FromBody] MyObject myObject)
    

To convert ASP.NET Web API's help pages to static html, you can use wget. For example,

wget -r -k -E http://<ip_address>/Help/

Reference:

Yeheshuah
  • 1,216
  • 1
  • 13
  • 28
-1

List routes using ActionDescriptor WITH http method (get,post etc)

[Route("")]
[ApiController]
public class RootController : ControllerBase
{
    private readonly IActionDescriptorCollectionProvider _actionDescriptorCollectionProvider;

    public RootController(IActionDescriptorCollectionProvider actionDescriptorCollectionProvider)
    {
        _actionDescriptorCollectionProvider = actionDescriptorCollectionProvider;
    }

    public RootResultModel Get()
    {
        var routes = _actionDescriptorCollectionProvider.ActionDescriptors.Items.Where(
            ad => ad.AttributeRouteInfo != null).Select(ad => new RouteModel
        {
            Name = ad.AttributeRouteInfo.Template,
            Method = ad.ActionConstraints?.OfType<HttpMethodActionConstraint>().FirstOrDefault()?.HttpMethods.First(),
            }).ToList();

        var res = new RootResultModel
        {
            Routes = routes
        };

        return res;
    }
}
Yeheshuah
  • 1,216
  • 1
  • 13
  • 28
  • Error CS0246 The type or namespace name 'IActionDescriptorCollectionProvider', 'IActionDescriptorCollectionProvider', 'RootResultModel', 'RouteModel', 'HttpMethodActionConstraint', 'RootResultModel' – Yeheshuah Nov 21 '19 at 07:08
-1

Perhaps this could help: a simple code snippet that you can add to the Configure method in the Startup class, that supposedly retrieve (at least in ASP.NET 3.1) the registered routes

Formalist
  • 349
  • 3
  • 12