Creating new HttpMessageHandler for HttpClient

Topics: Web Api
Dec 1, 2011 at 7:08 PM

Hi,

I am trying to create an HttpMessageHandler to add a custom Http Header for every outgoing request from the client (Asp.Net MVC app). I am struggling to understand whether I am on the right track because the majority of documentation appears to be for the Server side, not the consuming client. Anyway, I have created a handler that looks like similar to below:

 

    public class AddCustomHeaderHandler : DelegatingHandler {

        protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) {

            // Add the custom headers to the outgoing request...
            request.Headers.Add("X-UserContext", "UserId=whatever");

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

This is throwing an InvalidOperationException with the message: "The inner handler has not been assigned."

Does anyone know what I'm missing here?

Thanks

Coordinator
Dec 2, 2011 at 12:39 AM

A DelegatingHandler “delegates” the send call to an inner handler provided using the InnerHandler property. A DelegatingHandler is used to chain together message handlers in a Russian doll model. The error message is saying that the InnerHandler was not provided. Typically on the client you want the inner most handler to be an HttpClientHandler which will put the request on the wire and deal with the response.

Daniel Roth

Dec 2, 2011 at 1:06 AM

Perfect! I have amended the code accordingly and it's working now.

Thanks for your help.

Mar 13, 2012 at 2:47 PM

Any idea how to unit test a DelegatingHandler?  I'm guessing I need to wrap the handler in another handler?

        [TestMethod()]
        public void ApiKeyTest()
        {
 
            // arrange
            var cacheProvider = new MockCache();
            var partnerService = new MockPartnerService();
            var partnerKeyHandler = new PartnerKeyHandler(cacheProvider, partnerService);
            var httpClient = new HttpClient(partnerKeyHandler);
            var httpRequest = new HttpRequestMessage(HttpMethod.Get, "http://dev.null");
 
            httpRequest.Headers.Add("APIKEY""503B2176-254F-4F0E-8FBA-36843724E401");
 
            // act
            var responseMessage = httpClient.SendAsync(httpRequest);
            var actual = responseMessage.Result.IsSuccessStatusCode;
            var expected = true;
 
            // assert
            Assert.AreEqual(expected, actual);
        }
Mar 13, 2012 at 4:46 PM

That isn't exactly a unit test, that's a functional test.

Why don't you just invoke the delegating handler?

var x = new LoggingMessageHandler();
var r = new HttpRequestMessage();
// fill in request values necessary to test
var c = new CancellationToken();
// fill in cancellation token values here
var result = x.SendAsync(r, c);
// check if result was modified correctly