15

today i encountered a strange behavior in my Web Api application

protected void Application_Start() {

    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    GlobalConfiguration.Configuration
        .MessageHandlers.Add(new DummyMessageHandler());
}

And my DelegatingHandler looks like this.

public class DummyMessageHandler : DelegatingHandler {

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken) {

*       if (request.Headers.Authorization.Scheme == "Basic")
            Thread.CurrentPrincipal = new GenericPrincipal(
                new GenericIdentity("Authenticated"), new string[0]);

        return base.SendAsync(request, cancellationToken);
    }
}

The problem I encountered was that the delegating handlers are not being executed. I have a breakpoint in the line marked with a * and the execution of my code never stops there.

My nuget packages.config is the following:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.AspNet.Mvc" version="4.0.20710.0" targetFramework="net40" />
  <package id="Microsoft.AspNet.Razor" version="2.0.20710.0" targetFramework="net40" />
  <package id="Microsoft.AspNet.Web.Optimization" version="1.0.0" targetFramework="net40" />
  <package id="Microsoft.AspNet.WebApi" version="4.0.20710.0" targetFramework="net40" />
  <package id="Microsoft.AspNet.WebApi.Client" version="4.1.0-alpha-120809" targetFramework="net40" />
  <package id="Microsoft.AspNet.WebApi.Core" version="4.0.20710.0" targetFramework="net40" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="4.0.20710.0" targetFramework="net40" />
  <package id="Microsoft.AspNet.WebPages" version="2.0.20710.0" targetFramework="net40" />
  <package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net40" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net40" />
  <package id="Newtonsoft.Json" version="4.5.8" targetFramework="net40" />
  <package id="WebGrease" version="1.1.0" targetFramework="net40" />
</packages>

I'm looking at this for a long time, can you point me to something I am missing ? Thank you

3
  • 1
    I'm not able to reproduce your issue. In a newly created MVC4 Web.API project I've copied your DummyMessageHandler and registered it in the Application_Start and if I put a breakpoint there it is being hit. Commented Aug 17, 2012 at 0:19
  • Maybe the problem is happening because i have been updating this project since beta. I will install the last mvc4 and see if it solves it. Commented Aug 17, 2012 at 0:43
  • After installing mvc i created a project and all worked fine until I started adding packages with nuget. The result was this github.com/mccalltd/AttributeRouting/issues/112. Commented Aug 17, 2012 at 2:16

2 Answers 2

14

What you have done is correct. The problem might be happening because the DelegatingHandler only runs when you call a Web API Controller action. For example:

This will invoke your Message Handler, because it's an ApiController.

public class ValuesController : ApiController
{
    // GET api/values
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
}

This will NOT, because it's just a Controller.

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Title = "Home Page";

        return View();
    }
}

Make sure you are calling a Web API Controller action, otherwise the debugger will not hit your break point.

Sign up to request clarification or add additional context in comments.

2 Comments

Is it also possible to invoke the handler on a specific path, allthough there is no controller action mapped to it?
Had same issue and this solution worked for me. Looks like an implict/hidden requirement from ASP.NET, requiring a specific type of controller.
7

you should register your handler in the WebApiConfig file, not in the global.asax

 public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {

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


    }

6 Comments

-1 GlobalConfiguration.Configuration.MessageHandlers.Add() does work for adding Message Handlers to the pipeline. Further, if we do choose to add a Message Handler in the WebApiConfig, we use config.MessageHandlers.Add() not config.Filters.Add(). The latter is for adding Action Filters not Message Handlers.
@ShaunLuttin That was the valid point. Probably I mistyped Filters instead of MessageHandlers. Thanks
Thanks for updating the answer. Now, why do you say to register the handler in WebApiConfig instead of in the Global.asax. Both work and is a matter of style. Your answer is misleading; it implies that registering in Global.asax won't work. That's why the -1 stands.
Well, I said "You should" not "You must" to make registering message handlers more centralized. You are able to register a handler event even in your data access layer by accessing the global variable, but apparently that wouldn't be a recommended way.
Good point, Toan. It is better to register the DelegateHandler within WebApiConfig, as you suggest. The question, though, is about the handler not executing; it is not about the recommended place to register it. You're answer, while relevant and important, does not directly answer the question. That's why I haven't reversed the down vote.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.