如何获取 ASP.NET Core 中所有路由的列表?

问题描述:

在 ASP.NET Core 中,有没有办法查看 Startup 中定义的所有路由的列表?我们使用 IRouteBuilderMapRoute 扩展方法来定义路由.

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 of IRouteBuilder to define the routes.

我们正在迁移旧项目 WebAPI 项目.在那里我们可以使用 GlobalConfiguration.Configuration.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 = ???
    }
}

要获取所有路由,您需要使用 MVC 的 ApiExplorer 部分.您可以使用属性标记所有操作,也可以使用如下约定:

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

在 Startup.cs 中,将您的新添加到 ConfigureServices(...)

In Startup.cs, add your new in ConfigureServices(...)

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(
        options => 
        {
            options.Conventions.Add(new ApiExplorerVisibilityEnabledConvention());
            options.
        }
}

在您的 ActionFilter 中,您可以使用构造函数注入来获取 ApiExplorer:

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,其中包含 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>();
    }
}