0

I've got a .NET WebApi solution. I'm constraining access to HTTPS but conditionally allowing HTTP traffic. One of the conditions is that all HTTP requests must use the HTTP POST method, passing the x-http-method-override header to supply the intended method so the request can be properly routed. I've configured a global DelegatingHandler to validate all incoming requests and perform the redirection if needed.

With standard routing everything works great. When I configure AttributeRouting things go off the rails. It appears that AttributeRouting attempts to locate the route before the DelegatingHandler modifies the request, resulting in improper routes or IIS 404 errors. Is there a way to intercept the route before the AttributeRouting handler resolves the route?

More info: The project is hosted on IIS (not self hosted). The AttributeRouting I'm using is what comes in WebApi 2.0. The DelegatingHandler is defined thusly in App_Start:

GlobalConfiguration.Configuration.MessageHandlers
    .Add(new MyCustomDelegateHandler());

AttributeRouting is configured simply using:

GlobalConfiguration.Configuration.MapHttpAttributeRoutes();

The routes are defined using the attributes:

[HttpGet("api/test/v1/users")]
Chris Camaratta
  • 2,729
  • 22
  • 35
  • Thanks for the update...looks like you are using non-RTM bits of Web API 2 which probably had the issue you were talking about. In the RTM bits of Web API 2, you can no longer define a attribute route like above...please take a look here: http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2 – Kiran Nov 14 '13 at 19:44
  • Taking a look. Will let you know how it goes. – Chris Camaratta Nov 14 '13 at 19:55
  • Yea, updating the lib and changing from HttpGet to Route appears to resolve this issue. Mind updating your response with the fix and I'll accept it? – Chris Camaratta Nov 14 '13 at 20:46

1 Answers1

1

Couple of question for clarity...Is this a Selfhost or Webhost(IIS) scenario? By AttributeRouting you mean the built-in Web API 2 attribute routing and not TimMcCall's attribute routing nuget package...right?

There have always been differences between when route matching occurs between Selfhost and Webhost. In Selfhost, route matching happens after message handlers are run, where as in case of Webhost route matching happens before message handlers are run.

If your scenario is Webhost, then I would expect the behavior to not change...but if your are seeing different behavior, then can you share how your route configuration (WebApiConfig.cs & the attributed controller/action) look like?

In Webhost, to intercept requests before route matching happens, you could create a Owin middleware which sits before the request is received by Web API. In this middleware you can modify the request details as you need.

NOTE:
Based on the update "More Info" in the post above, pre-RTM bits were being used where this seems to be an issue and this is not longer a problem with the final RTM bits.

Kiran
  • 56,921
  • 15
  • 176
  • 161
  • According to [this, official, poster](http://www.asp.net/posters/web-api/ASP.NET-Web-API-Poster.pdf), there is no difference between self hosted and IIS hosted handling of request. Delegating handlers in both settings run _before_ the routing kicks in. And I have observed both self hosted (at work) and IIS hosted (at home) behaving the same way: delegating handlers getting at the request before any routing takes place. Do you have any sample projects to reproduce what you are saying? – Marjan Venema Nov 14 '13 at 19:01
  • The poster doesn't clearly say when the route-matching happens actually. A simple repro of what i am saying is: Create a new Web API project and then remove any existing configuration from WebApiConfig.cs and then create a simple delegating handler and have something like this `config.MessageHandlers.Add(new HandlerA()); config.Routes.MapHttpRoute("DefaultApi", "api/values", new { controller = "Values" });`...When you make a request for `api/values`, you should see the handler getting invoked...but when you make a request like `api/test`, the handler is never invoked – Kiran Nov 14 '13 at 19:11
  • Continuing on my previous comment, since in the case when request is `api/test` and the handler is never invoked, this indicates that route matching is happening BEFORE the message handlers are run. – Kiran Nov 14 '13 at 19:38
  • Agreed. Looking at the posted I'd have thought route matching happens after the delegatinghandler is invoked, but this doesn't seem to be the case. I've added some clarifying details in my original post. – Chris Camaratta Nov 14 '13 at 19:41
  • @Chris and Kiran: MVC and web api routing can be mixed. VS adds a default MVC route to the configuration of a new web api project to cater to the `help area` which are the MVC based "help pages" for your api. Could it be that this default MVC route is throwing things off? Then again, the poster also seems to imply that OnActionExecuted isn't triggered when an exception occurs and I have recently found out that it actually does... [Web Api REST service exception handling issue](http://stackoverflow.com/questions/19870461/) – Marjan Venema Nov 14 '13 at 19:59
  • @MarjanVenema - I've removed all default routes, and anything related to MVC. If I'm not using Attribute Routing, things work as expected, so whatever the issue is AR is definitely involved somehow. – Chris Camaratta Nov 14 '13 at 20:10
  • @ChrisCamaratta: So attribute routing is throwing a spanner in the works... Wow. Wouldn't have expected that it would make such a big difference. Good to know. Thanks for sharing that. – Marjan Venema Nov 14 '13 at 20:16
  • The lib was out of date. This doesn't appear to be an issue in the RTM version. – Chris Camaratta Nov 14 '13 at 20:46