8

In my Web API handler I need to get the name of the route that matched the request.

public class CurrentRequestMessageHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var route = request.GetRouteData().Route;
        //now what?

        return base.SendAsync(request, cancellationToken);
    }
}
Kara
  • 6,115
  • 16
  • 50
  • 57
Ventsyslav Raikov
  • 6,882
  • 1
  • 25
  • 28
  • The route's name probably is only available in the route collection accessible from the web configuration. Not sure how you would gain access to the configuration from a delegating handler through. – Marjan Venema Nov 08 '13 at 11:11
  • @MarjanVenema I can get that from GlobalConfiguration.Configuration.Routes but then how do I find my route there? I guess it's not the same object and don't like the idea to search based on the route template. Even if I find it in the route's collection - the objects there are IHttpRoute which doesn't expose any name properties. – Ventsyslav Raikov Nov 08 '13 at 11:17
  • Not sure either, but I wouldn't be surprised if they were the same object as the request (IIUC) gets it added to its property collection from the route collection when the controller and action method are selected. I'd say try finding the route in the collection based on the assumption that it refers to the same instance (it is an interface after all) and see what you get/how you get on stepping through (or logging info). – Marjan Venema Nov 08 '13 at 11:22
  • Could your give more details about your scenario...curious as to why do you need the current route's name? Currently you cannot retrieve a route name in Web API for a given route... – Kiran Nov 08 '13 at 16:13
  • @KiranChalla - are you 100% sure that there is no way? If yes - post it as an answer with some proof/explanation and I'll accept it. My scenario is complicated - I have an IOC with some objects/factories that generate hypermedia links. On the request coming in I need to register some instances in the IOC that will be able to generate those links by using the URLHelper class - which needs a route name to generate a link. – Ventsyslav Raikov Nov 08 '13 at 16:26
  • http://stackoverflow.com/questions/25222277/web-api-get-route-template-from-inside-handler – shanavascet Aug 12 '16 at 13:39

2 Answers2

8

Currently there is no way to retrieve the route name of a route in Web API. You can take a look at the HttpRouteCollection source code here for more details. If route name is definitely required for your scenario, you could stick in the route name in the data tokens of a route. (note that currently attribute routing doesn't provide a way to access the data tokens)

Update - 6/23/2014
With latest improvements(5.2 RC) in the area of attribute routing, you can do something like following to insert route names into data tokens.

config.MapHttpAttributeRoutes(new CustomDefaultDirectRouteProvider());

public class CustomDefaultDirectRouteProvider : DefaultDirectRouteProvider
{
    public override IReadOnlyList<RouteEntry> GetDirectRoutes(HttpControllerDescriptor controllerDescriptor, 
        IReadOnlyList<HttpActionDescriptor> actionDescriptors, IInlineConstraintResolver constraintResolver)
    {
        IReadOnlyList<RouteEntry> coll = base.GetDirectRoutes(controllerDescriptor, actionDescriptors, constraintResolver);

        foreach(RouteEntry routeEntry in coll)
        {
            if (!string.IsNullOrEmpty(routeEntry.Name))
            {
                routeEntry.Route.DataTokens["Route_Name"] = routeEntry.Name;

            }
        }

        return coll;
    }
}

Access it like this:
reequest.GetRouteData().Route.DataTokens["Route_Name"]

Kiran
  • 56,921
  • 15
  • 176
  • 161
  • If someone is looking for how to add `DataTokens` in `WebApiConfig` using Web API 2.1, see [note 2 in this answer](http://stackoverflow.com/a/10471854/700926). – Lasse Christiansen Jun 24 '14 at 05:39
1

It's perhaps a bit late to answer this, but I found myself in the same situation (that is I need to generate an URL while not having the corresponding IHttpRoute name). You can however generate an URL with just the Route and the HttpRequestMessage.

var parameters = new Dictionary{{"id" , 123}, {HttpRoute.HttpRouteKey, true}};
var path = Route.GetVirtualPath(request, parameters);
var uri = path.VirtualPath;

The important part is to add HttpRoute.HttpRouteKey to the parameters, if this value is not used GetVirtualPath returns null. see code in HttpRoute.cs

// Only perform URL generation if the "httproute" key was specified. This allows these
// routes to be ignored when a regular MVC app tries to generate URLs. Without this special
// key an HTTP route used for Web API would normally take over almost all the routes in a
// typical app.
if (values != null && !values.Keys.Contains(HttpRouteKey, StringComparer.OrdinalIgnoreCase))
{
    return null;
}