Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
154 views
in Technique[技术] by (71.8m points)

c# - get a list of attribute route templates asp.net webapi 2.2

I have a .NET project running in C# using WebApi 2.2.

I am registering all of my routes using attributes. What I would like to do is pro grammatically retrieve all of the attribute route templates as strings.

Something like: var routeTemplates = System.Web.Routing.RouteTable.Routes.Select(x => x.RouteTemplates);

I am able to see all of the the routes when I put a watch on ControllerContext.Configuration.Routes

However, I cannot seem to access the routes from my code as they are protected internals. How do I get at them?

I've attached a screen shot which shows the values I am seeing on my locals watch that I need to get at.

The data I want to get at

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When registering the attribute routes in Web API you can register a custom IDirectRouteProvider to customize how attribute routes are found. In that custom IDirectRouteProvider you can delegate all the "hard" work to the default implementation, DefaultDirectRouteProvider, that looks at all the controllers and actions to compute the list of attribute routes, and then take credit for all that hard work.

To set this all up, first create a new "observable" direct route provider that delegates all its work:

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

And then use this new class from the WebApiConfig.Register method in your app's startup:

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

Note that the data is ultimately stored in a static field. This is required because the code inside WebApiConfig.Register is not called immediately - it's called later in global.asax.cs. So, to observe the results of everything, add some code to 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'
}

And in a little test I wrote, I got these values:

enter image description here

And there you have it, a list of all the attribute routes in the app!

Note: There's additional data squirrelled away in the DataTokens property of each route if you want to figure out where each attribute route came from.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...