Получить список атрибутов шаблонов маршрутов asp.net webapi 2.2

У меня есть проект .NET, работающий на С# с использованием WebApi 2.2.

Я регистрирую все свои маршруты, используя атрибуты. То, что я хотел бы сделать, это программно получить все шаблоны маршрутов атрибутов в виде строк.

Что-то вроде: var routeTemplates = System.Web.Routing.RouteTable.Routes.Select(x => x.RouteTemplates);

Я могу видеть все маршруты, когда ставил часы на ControllerContext.Configuration.Routes

Однако я не могу получить доступ к маршрутам из моего кода, так как они защищены внутренними. Как мне добраться до них?

Я добавил скриншот, который показывает значения, которые я вижу на моем locals watch, который мне нужно получить.

The data I want to get at

Ответ 1

При регистрации маршрутов атрибутов в Web API вы можете зарегистрировать пользовательский IDirectRouteProvider, чтобы настроить, как найти маршруты атрибутов. В этом пользовательском IDirectRouteProvider вы можете делегировать всю "жесткую" работу на реализацию по умолчанию, DefaultDirectRouteProvider, которая просматривает все контроллеры и действия для вычисления списка маршрутов атрибутов, а затем берет на себя ответственность за всю эту тяжелую работу.

Чтобы установить все это, сначала создайте новый "наблюдаемый" поставщик прямых маршрутов, который делегирует всю свою работу:

public class ObservableDirectRouteProvider : IDirectRouteProvider
{
    public IReadOnlyList<RouteEntry> DirectRoutes { get; private set; }

    public IReadOnlyList<RouteEntry> GetDirectRoutes(HttpControllerDescriptor controllerDescriptor, IReadOnlyList<HttpActionDescriptor> actionDescriptors, IInlineConstraintResolver constraintResolver)
    {
        var realDirectRouteProvider = new DefaultDirectRouteProvider();
        var directRoutes = realDirectRouteProvider.GetDirectRoutes(controllerDescriptor, actionDescriptors, constraintResolver);
        // Store the routes in a property so that they can be retrieved later
        DirectRoutes = DirectRoutes?.Union(directRoutes).ToList() ?? directRoutes;
        return directRoutes;
    }
}

И затем используйте этот новый класс из метода WebApiConfig.Register в вашем приложении:

public static class WebApiConfig
{
    public static ObservableDirectRouteProvider GlobalObservableDirectRouteProvider = new ObservableDirectRouteProvider();

    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes(GlobalObservableDirectRouteProvider);

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

Обратите внимание, что данные в конечном итоге сохраняются в статическом поле. Это необходимо, потому что код внутри WebApiConfig.Register не вызывается сразу - он называется позже в global.asax.cs. Итак, чтобы наблюдать за результатами всего, добавьте код Application_Start:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    var allDirectRoutes = WebApiConfig.GlobalObservableDirectRouteProvider.DirectRoutes;
    // now do something with 'allDirectRoutes'
}

И в небольшом тесте, которое я написал, я получил следующие значения:

enter image description here

И там у вас есть список всех маршрутов атрибутов в приложении!

Примечание. В свойстве DataTokens каждого маршрута есть дополнительные данные, если вы хотите выяснить, откуда пришел маршрут атрибута.