Capturing Redirects with HttpClient

Home / Capturing Redirects with HttpClient

A while back, I blogged about a pattern of accessing API’s with .NET’s HttpClient. In practice, one problem with .NET’s HttpClient is that it doesn’t provide any insight regarding Http redirects.


By default, HttpClient follows redirects without making any fuss. Most of the time, letting HttpClient follow redirects for you works well enough. In a current application, though, when using generic/reusable service methods, I need to know the final redirect in some cases. The final redirect lets me know when I can trigger other actions in a particular work-flow.

If we pass an HttpClientHandler to the HttpClient, it has a property to allow prevention of automatic redirection. The property is “AllowAutoRedirect.” The setup then looks like the below code. Since the HttpClient doesn’t follow redirects, we can check the status code and perform our own logic on redirects. You can see in the handling of the redirect, the “MakeRequest” method effectively becomes a recursive routine. A redirect can specify an absolute or relative URL. This must be handled as indicated in the code as well.

public bool MakeRequest(url)
{
    using (var client = new HttpClient(new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip }) { Timeout = _timeout })
    {
        var request = new HttpRequestMessage()
        {
            RequestUri = new Uri(url),
            Method = HttpMethod.Get
        };

        HttpResponseMessage response = client.SendAsync(request).Result;
        var statusCode = (int)response.StatusCode;

        // We want to handle redirects ourselves so that we can determine the final redirect Location (via header)
        if (statusCode >= 300 && statusCode <= 399)
        {
            var redirectUri = response.Headers.Location;
            if (!redirectUri.IsAbsoluteUri)
            {
                redirectUri = new Uri(request.RequestUri.GetLeftPart(UriPartial.Authority) + redirectUri);
            }
            _status.AddStatus(string.Format("Redirecting to {0}", redirectUri));
            return MakeRequest(redirectUri);
        }
        else if (!response.IsSuccessStatusCode)
        {
            throw new Exception();
        }

        return true;
    }
}

Leave a Reply