In an ASP.NET 4.5 MVC 4 Web API project, I want to add a custom HttpMessageHandler
. I've changed WebApiConfig
class (in \App_Satrt\WebApiConfig.cs), as follows:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: null,
handler: new MyCustomizedHttpMessageHandler()
);
}
}
Then I developed MyCustomizedHttpMessageHandler
:
public class MyCustomizedHttpMessageHandler : HttpMessageHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
IPrincipal principal = new GenericPrincipal(
new GenericIdentity("myuser"), new string[] { "myrole" });
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
return Task<HttpResponseMessage>.Factory.StartNew(() => request.CreateResponse());
}
}
However, the request to the API (let's say http://mylocalhost.com/api/values), always returns status code 200, without any data. I mean it never gets to ValuesController.cs's 'GET()' method.
What have I missed? How can I implement HttpMessageHandler
properly?
PS: Have already read this one: https://stackoverflow.com/a/12030785/538387 , doesn't help me.
A message handler is a class that receives an HTTP request and returns an HTTP response. Message handlers derive from the abstract HttpMessageHandler class. Typically, a series of message handlers are chained together.
Web API Delegate Handler Further it travels in pipeline as HttpRequestMessage in Pipeline. They process HTTP request messages on the way in, and HTTP response messages on the way out. To create a custom message handler, derive from the DelegatingHandler class. You can add multiple message handlers.
Adding Message Handlers to the Client Pipeline HttpClient client = HttpClientFactory. Create(new Handler1(), new Handler2(), new Handler3()); Message handlers are called in the order that you pass them into the Create method. Because handlers are nested, the response message travels in the other direction.
In a message handler, a series of message handlers are chained together. The first handler receives an HTTP request, does some processing, and gives the request to the next handler. At some point, the response is created and goes back up the chain. This pattern is called a delegating handler.
Here you are creating a HttpMessageHandler
which short circuits the request and doesn't let the request pass through the rest of the pipeline. Instead, you should create a DelegatingHandler
.
Also there are 2 kinds of message handler pipelines in Web API. One is a regular pipeline in which all requests for all routes pass through and other where one could have message handlers specific to certain routes only.
Try to create a DelegatingHandler
and add it to your HttpConfiguration
's list of message handlers:
config.MessageHandlers.Add(new HandlerA())
If you want to add a route specific message handler, then you could do the following:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: null,
handler:
HttpClientFactory.CreatePipeline(
new HttpControllerDispatcher(config),
new DelegatingHandler[]{new HandlerA()})
);
This Web Api Poster shows the pipeline flow.
To write a custom message handler, you should derive from System.Net.Http.DelegatingHandler
class CustomMessageHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage>
SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
IPrincipal principal = new GenericPrincipal(
new GenericIdentity("myuser"), new string[] { "myrole" });
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
return base.SendAsync(request, cancellationToken);
}
}
And call base.SendAsync
to send the request to the inner handler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With