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

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

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

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

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

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

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

Данные, которые я хочу получить

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

И в небольшом тесте, который я написал, я получил эти значения:

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

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

Другие вопросы по тегам