web api get route template from inside handler

谁都会走 提交于 2019-12-01 03:54:12

The Web Api still has a lot to improve. It was tricky to find a way to get this working and I just hope this saves other guys from spending all the time I did.

 var routeTemplate = ((IHttpRouteData[]) request.GetConfiguration().Routes.GetRouteData(request).Values["MS_SubRoutes"])
                                    .First().Route.RouteTemplate;

I had a similar issue, but was able to get the route inside the message handler by the following:

request.GetConfiguration().Routes.GetRouteData(request).Route.RouteTemplate;

Nick Turner

The answer from Marco (shown below) is correct so long as there isn't more than one route defined with the same HttpMethod. The .First() will grab the 1st route defined in that specific ApiController, but this doesn't ensure it grabs the correct one. If you use the ControllerContext to get the Route, you can be sure you've got the exact endpoint you want.

Marco's:

var routeTemplate = ((IHttpRouteData[])request.GetConfiguration()
                     .Routes.GetRouteData(request).Values["MS_SubRoutes"])
                     .First().Route.RouteTemplate;

The code:

((IHttpRouteData[])request.GetConfiguration()
                     .Routes.GetRouteData(request).Values["MS_SubRoutes"])

actually returns a collection of IHttpRouteData, and it contains a record for each endpoint which has the same HttpMethod (Post, Get, etc)... The .First() doesn't guarantee you get the one you want.

Guaranteed To Grab Correct Endpoint's RouteTemplate:

public static string GetRouteTemplate(this HttpActionContext actionContext)
{
    return actionContext.ControllerContext.RouteData.Route.RouteTemplate;
} 

I used an extension method so to call this you'd do:

var routeTemplate = actionContext.GetRouteTemplate();

This will assure that you get the specific RouteTemplate from the endpoint making the call.

I think you can get route Data from request.Properties property and easy to unit test.

/// <summary>
    /// Gets the <see cref="System.Web.Http.Routing.IHttpRouteData"/> for the given request or null if not available.
    /// </summary>
    /// <param name="request">The HTTP request.</param>
    /// <returns>The <see cref="System.Web.Http.Routing.IHttpRouteData"/> or null.</returns>
    public static IHttpRouteData GetRouteData(this HttpRequestMessage request)
    {
        if (request == null)
        {`enter code here`
            throw Error.ArgumentNull("request");
        }

        return request.GetProperty<IHttpRouteData>(HttpPropertyKeys.HttpRouteDataKey);
    }

    private static T GetProperty<T>(this HttpRequestMessage request, string key)
    {
        T value;
        request.Properties.TryGetValue(key, out value);
        return value;
    }

Reference link of code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!