In two previous blogs I describe how to use HttpClient as well as how to use the HttpMessageHandler pipeline. What we haven’t done explicitly is showing when and how to use HttpClient, HttpClientHandler, and WebRequestHandler. This is the purpose of this blog.
The first thing to remember is that HttpClient uses the HttpMessageHandler pipeline for sending and receiving requests. The default handler implementations (HttpClientHandler and WebRequestHandler) both sit on top of HttpWebRequest which has a lot of properties for controlling how to deal with requests and responses. However, in order to stay simple, HttpClient doesn’t expose all these properties up front – it would make it unwieldy and show a lot of things that are rarely used.
If you need to access these properties then there are two ways of doing it: use either HttpClientHandler or WebRequestHandler. Both are HttpMessageHandlers hooked in as part of the HttpMessageHandler pipeline. Below we will describe when and how to use these handlers, how they differ, as well as how to combine them with your own handlers.
You can find this code for this sample in the aspnet.codeplex.com code repository and there are instructions here for how to use the samples.
The default HttpClient is the simplest way in which you can start sending requests. A single HttpClient can be used to send as many HTTP requests as you want concurrently so in many scenarios you can just create one HttpClient and then use that for all your requests.
HttpClient has a few properties that are commonly used and which you can set up until the point where you start sending requests, namely:
Here’s an example of how to create a simple HttpClient and issue a request while setting the timeout for all requests:
1: // Create an HttpClient and set the timeout for requests
2: HttpClient client = new HttpClient();
3: client.Timeout = TimeSpan.FromSeconds(10);
4:
5: // Issue a request
6: client.GetAsync(_address).ContinueWith(
7: getTask =>
8: {
9: if (getTask.IsCanceled)
10: {
11: Console.WriteLine("Request was canceled");
12: }
13: else if (getTask.IsFaulted)
14: {
15: Console.WriteLine("Request failed: {0}", getTask.Exception);
16: }
17: else
18: {
19: HttpResponseMessage response = getTask.Result;
20: Console.WriteLine("Request completed with status code {0}", response.StatusCode);
21: }
22: });
If you have additional handlers which you want to wire up as well then the simplest way is to use the HttpClientFactory class. Here’s an example wiring up 3 custom message handlers:
1: // Create an HttpClient and add message handlers for the client
2: HttpClient client = HttpClientFactory.Create(
3: new SampleHandler("Client A", 2),
4: new SampleHandler("Client B", 4),
5: new SampleHandler("Client C", 6));
HttpClientHandler is an HttpMessageHandler with a common set of properties that works across most versions of the HttpWebRequest API. This is the default handler and so is what you get if you use the default constructor. However, in order to actually get access to the various properties (see below) you have to explicitly create it and then pass it to HttpClient.
Here’s an example of how to create an HttpClientHandler, set a property, and pass it to HttpClient:
1: // Create HttpClientHandler and set UseDefaultCredentials property
2: HttpClientHandler clientHandler = new HttpClientHandler();
3: clientHandler.UseDefaultCredentials = true;
5: // Create an HttpClient using the HttpClientHandler
6: HttpClient client = new HttpClient(clientHandler);
Like above, you can combine your HttpClientHandler instance with other custom handlers, here’s what it looks like:
5: // Create an HttpClient and add message handlers for the client
6: HttpClient client = HttpClientFactory.Create(
7: clientHandler,
8: new SampleHandler("Client A", 2),
9: new SampleHandler("Client B", 4),
10: new SampleHandler("Client C", 6));
WebRequestHandler derives from HttpClientHandler but adds properties that generally only are available on full .NET. The WebRequestHandler is not included in the System.Net.Http DLL but rather in System.Net.Http.WebRequest DLL so you have to explicitly include that as a reference in order to see it. Otherwise it won’t show up.
Here’s an example of how to create an WebRequestHandler, set a property, and pass it to HttpClient:
1: // Create WebRequestHandler and set UseDefaultCredentials and AllowPipelining (for HTTP) properties
2: WebRequestHandler webRequestHandler = new WebRequestHandler();
3: webRequestHandler.UseDefaultCredentials = true;
4: webRequestHandler.AllowPipelining = true;
5:
6: // Create an HttpClient using the WebRequestHandler
7: HttpClient client = new HttpClient(webRequestHandler);
Again, you can combine the WebRequestHandler with your own handlers as well – here’s what it looks like:
6: // Create an HttpClient and add message handlers for the client
7: HttpClient client = HttpClientFactory.Create(
8: webRequestHandler,
9: new SampleHandler("Client A", 2),
10: new SampleHandler("Client B", 4),
11: new SampleHandler("Client C", 6));
Have fun!
Henrik