HTTP Message Handler in Web API: Real Time Implementation of Message Handler

In this article we will see a few real-time applications with a custom HTTP Message Handler.

This is the “HTTP Message Handler in Web API” article series. In our previous two articles we learned the basic concepts of Message Handlers and the execution of HTTP custom Message Handlers. You can read them here.

HTTP Message Handler in Web API

In this article we will see a few real-time applications with a custom HTTP Message Handler. Though those examples are not full-fledge examples ready for a production server but they provide an idea of custom HTTP handlers.

As in the previous explanation we have learned that we can inject our custom Message Handler within a system Message Handler and we can form the handler chain. When a HTTP request arrives at the controller, it will pass through those custom handlers.

So, the custom handlers are a good place to perform some business logic and security implementation. For example there might be a condition in the Web API that only the HTTPS protocol can access the application. Let’s implement it in our custom Message Handler.

Allow only HTTP protocol to access the application

Step 1: Implementation of custom Message Handler

In this step we will implement a custom Message Handler that will filter the HTTP request. We have implemented a MessageHandler1 class derived from the DelegatingHandler class. Within that we are checking the HTTP type using a request object.

public class MessageHandler1 : DelegatingHandler

{

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

    {

        if (!String.Equals(request.RequestUri.Scheme, "https", StringComparison.OrdinalIgnoreCase))

        {

                 return await Task.Factory.StartNew(() =>

         {

         return new HttpResponseMessage(HttpStatusCode.BadRequest)

         {

             Content = new StringContent("HTTPS is Required to access the application")

         };

      });

  }

  return await base.SendAsync(request, cancellationToken);

  }

}


When the type is HTTP, we are creating one response message with response type “Bad Request”. In other words, we are not allowing the request to move towards a controller and within the custom Message Handler we are generating a response.

Step 2: Register the custom Message Handler

If it is necessary to register a custom Message Handler then we can inject our own Message Handler logic into a HTTP request and response pipeline.

protected void Application_Start()

{

   WebApiConfig.Register(GlobalConfiguration.Configuration);

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

}

Step 3: Implement sample controller

This is a small stub controller that we will call from a browser window. We have just modified the default values of the controller by adding a Get() action.
 

public class ValuesController : ApiController

{

    //api/Get

    public string[] Get()

    {

        return new string[] { "Sourav", "Kayal" };

    }

}

Yes, we have configured all settings, now let’s run the application. If we are lucky enough then we will see the following output screen.

So the response is returning from our custom Message Handler.

custom message handler

Restrict specific method in custom Message Handler

Again, your business requirement might be that you will not allow specific HTTP requests to your controller. Within a custom Message Handler we can check the HTTP request type, if it is a GET request then we will drop the request there and we will return one custom response message. Have a look at the following code.

Here is the complete code of the Global.aspx page

In the MessageHandler1 class we are checking the request type using a method property of the request object. And if it is a GET then generate our custom response otherwise process the request for the next Message Handler.
 

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Linq;

using System.Net;

using System.Net.Http;

using System.Threading;

using System.Threading.Tasks;

using System.Web;

using System.Web.Http;

using System.Web.Http.Filters;

using System.Web.Http.WebHost;

using System.Web.Mvc;

using System.Web.Optimization;

using System.Web.Routing;

using System.Web.SessionState;

 

namespace TestWEB_API

{  

    public class WebApiApplication : System.Web.HttpApplication

    {

        protected void Application_Start()

        { 

            WebApiConfig.Register(GlobalConfiguration.Configuration);

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

            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

            RouteConfig.RegisterRoutes(RouteTable.Routes);

            BundleConfig.RegisterBundles(BundleTable.Bundles);

        }

    } 

    public class MessageHandler1 : DelegatingHandler

    {      

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

            {

                if (request.Method == HttpMethod.Get)

                {

                    var response = new HttpResponseMessage(HttpStatusCode.OK)

                     {

                          Content = new StringContent("GET method is not allowed in this application")

                     };          

                    var tsc = new TaskCompletionSource<HttpResponseMessage>();

                    tsc.SetResult(response);  

                    return await tsc.Task;

                }

                else

                {

                    var response = await base.SendAsync(request, cancellationToken);

                    return response;

                }               
            }
    }

}


The following is the implementation of the sample controller of which we will call using a GET request.

 
public class ValuesController : ApiController

{

    //api/Get

    public string[] Get()

    {

        return new string[] { "Sourav", "Kayal" };

    }

}

 
Now when we try to reach the preceding controller‘s Get() action we will encounter the following output. It’s throwing the custom response that we have set in our own Message Handler.

message handler

Conclusion

In this article we have learned a few important tips that we can implement in a custom Message Handler. I hope they will help you to implement better and secure Web API applications. Keep reading this series. I will return shortly with a few more tips and examples.