HTTP Message Handler in Web API: Execution Flow of Custom Message Handler

In this article we will understand the execution flow of the message handler chain.

This is the HTTP Message Handler in Web API article series. In our previous example we learned to implement server-side message handler in the Web API. You can read it here.

HTTP Message handler in Web API: Implement server-side message handler

In the previous article we had ended with the implementiion of the message handler chain but we did not explain the execution flow of the message handler chain. In this article we will understand the execution flow of the message handler chain.

The golden rule of a message handling sequence is that the execution occurs in the order of their registration. In other words, if there are two message handlers called “Message1” and “Message2” and if they are registered in the following sequence:

Register Message1()
Register Message2()

Then Message1 will execute first and Message2 will execute next after Message1 at the time of the incoming request.

The incoming mesages determines that the HTTP request will come from an external network and it will flow towards the controller and action. At the time of the outgoing response the fashion is the opposite of incoming. The last message handler will execute first and the first message handler will execute last. Like as in a bottom-up fashion.

Here we will demonstrate a small example to prove the concept. Let’s implement the following example.

Implement message handler chain

We will implement a message handler chain to understand the execution process. The functionality of MessageHandler1 and MessageHandler2 are not much complex. We wil just track the execution with a few debug statements.

    public class MessageHandler1 : DelegatingHandler
    {
       
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
        {
           
Debug.WriteLine("Begining of Message Handler 1");
           
// Call the inner handler.
           
var response = await base.SendAsync(request, cancellationToken);
           
Debug.WriteLine("End of Message Handler 1");
           
return response;
        }
    }

   
public class MessageHandler2 : DelegatingHandler
    {
       
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
        {
           
Debug.WriteLine("Begining of Message Handler 2");
           
// Call the inner handler.
           
var response = await base.SendAsync(request, cancellationToken);
           
Debug.WriteLine("End of Message Handler 2");
           
return response;
        }
    }


Ok, so we have defined two message handlers in the Global.asax page and now we will register them. Here is the registration process.

protected
void Application_Start()
 {

           
WebApiConfig.Register(GlobalConfiguration.Configuration);
           
GlobalConfiguration.Configuration.MessageHandlers.Add(new MessageHandler1());
           
GlobalConfiguration.Configuration.MessageHandlers.Add(new MessageHandler2());
 }

So, consistent with our theoretical explanation, we have registered MessageHandler1() at first and then MessageHandler2() .

Now we will implement one dummy controller and action just to execute the process. Here is the code for that.

    public class ValuesController : ApiController
    {
       
//api/Get
       
public string[] Get()
        {
           
return new string[] {"Sourav","Kayal" };
        }
    }

When this Get() method is called we will observe the execution of the message handler. Let’s look at the following output.



This is the output, when the request arrives at the controller and action, we see that MessageHandler1 has executed first and then Message handler2. Since we are calling the SendAsync() function asynchronously, it’s not waiting for MessageHandler1 to finish, It’s immediately moving towards MessageHandler2.

Here is the pipeline output of the HTTP response sequence.



We are seeing that the control has stuck to MessageHandler2 at first and then MessageHandler1. In other words at the time of the HTTP response the execution step has changed in reverse order.

Conclusion

In this small article we have learned the execution sequence of a HTTP custom message handler. I hope you have understood it. In a future article we will play around more with HTTP message handlers.