Search code examples
asp.net-web-apiasp.net-web-api2asp.net-web-api-routingasp.net-routing

ASP.NET Web API custom message handler per route and global


I have 3 ASP.NET Web API message handlers:

  • Handler1
  • Handler2
  • AuthorizeHandler

Handler1 and Handler2 are global (applying to all routes) and one single handler (AuthorizeHandler) applies to one single route.

However I have some issues in implementing this:

  public static void Register(HttpConfiguration config)
    {            
        config.MessageHandlers.Add(new Handler1());  //this will apply to all routes
        config.MessageHandlers.Add(new Handler2());  //this will apply to all routes


        config.MapHttpAttributeRoutes();


        config.Routes.MapHttpRoute(
          name: "FreeAPI",
          routeTemplate: "api/free/{controller}/{action}/{id}",
          defaults: new { id = RouteParameter.Optional }
        );


        config.Routes.MapHttpRoute(
            name: "SecretAPI",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: null,
            handler: new AuthorizeHandler()  // this will apply just to this route
                         { 
                            InnerHandler = new HttpControllerDispatcher(config) 
                         }
        );       

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }

Basically what I try to do is create an anonymous route where anybody can call without authentication and one single route that needs authentication in order to access it.

However this implementation I did it doesn't work.

For example I want to have this endpoint: api/free/someanonymouscontroller/someanonymousaction/someanonymousid as anonymous and this endpoint api/somesecurecontroller/somesecureaction/somesecureid as secure that needs authentication.

If I use fiddler to test it, on this endpoint: api/somesecurecontroller/somesecureaction/somesecureid I cannot access it without credentials instead if I use this ednpoint: api/free/somesecurecontroller/somesecureaction/somesecureid (notice the free path) I can access a secure endpoint without the handler to trigger ...


Solution

  • Hmm,

    I made the following changes and seams to work. I removed from template {controller} and added to defaults controller="free". Now all requests are going to the right place ...

    Is this the correct way?

        config.Routes.MapHttpRoute(
          name: "FreeAPI",
          routeTemplate: "api/free/{action}/{id}",
          defaults: new { controller="free", id = RouteParameter.Optional }
        );