不使用“ RoutePrefix”或“ Route”属性时,获取所有路由的列表(ASP.NET)

时间:2019-11-21 06:28:15

标签: c# asp.net asp.net-web-api

我有几个如下的路由模板,以及很多包含多个端点的控制器。

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 }
        );
    }
}

如何根据现有Controller及其方法获取所有路由(端点)的列表?


我希望得到类似的东西:

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

以此类推。


更新#1

我尝试了查尔斯的建议,但似乎只显示了路线模板 Charles' advice


更新#2

我尝试了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);
+            }
         }

我能够获取端点列表,但是该列表并不包含所有端点。
据我了解,该列表包括端点,那里有明确的路由属性,例如:

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

但是未附加RoutePrefixRoute的端点未包括在列表中。

3 个答案:

答案 0 :(得分:0)

当没有使用RoutePrefixRoute属性时,我没有找到获取所有路由列表(ASP.NET)的方法,但是以下解决方案对我有所帮助。
※我认为当RoutePrefixRoute属性未使用时,不可能获得所有路由的正确列表。

  1. 安装Microsoft.AspNet.WebApi.HelpPage程序包。
    工具→NuGet软件包管理器→软件包管理器控制台
    PW> Install-Package Microsoft.AspNet.WebApi.HelpPage
    
  2. 如下编辑XXXProject \ Global.asax.cs的Application_Start方法。
    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);
        AreaRegistration.RegisterAllAreas(); // ★Add this line
    }
    
  3. 如下编辑XXXProject \ Areas \ HelpPage \ App_Start \ HelpPageConfig.cs的Register方法。
    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. 启用XML文档文件。
    解决方案资源管理器→右键单击项目→选择属性→选择构建页面
    在文本字段中输入“ App_Data / XmlDocument.xml”。 XML documentation

用于获取正确的ASP.NET Web API帮助页面的属性。

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

要将ASP.NET Web API的帮助页面转换为静态html,可以使用wget。 例如,

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

参考:

答案 1 :(得分:0)

也许this可以帮助您:一个简单的代码段,您可以将其添加到 Startup 类的 Configure 方法中,该代码段应该可以检索(至少在ASP.NET 3.1)注册路由

答案 2 :(得分:-1)

使用ActionDescriptor和HTTP方法列出路由(获取,发布等)

[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;
    }
}
相关问题