46

I have the following method that returns the Http status code of a given Url:

public static async void makeRequest(int row, string url)
{
    string result;
    Stopwatch sw = new Stopwatch(); sw.Start();

    try
    {
        using (HttpClient client = new HttpClient())
        {
            HttpResponseMessage response = new HttpResponseMessage();
            response = await client.GetAsync(url);

            // dump contents of header
            Console.WriteLine(response.Headers.ToString());

            if (response.IsSuccessStatusCode)
            {
                result = ((int)response.StatusCode).ToString();
            }
            else
            {
                result = ((int)response.StatusCode).ToString();
            }
        }
    }
    catch (HttpRequestException hre)
    {
        result = "Server unreachable";
    }

    sw.Stop();
    long time = sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L));

    requestComplete(row, url, result, time);
}

It works well for 200/404 etc, however in the case of 301 codes I believe the returned result is the already-redirected (200) result, rather than the actual 301 that should be returned and which would have a header containing where the redirect would be pointed to.

I have seen something like this in other .Net web requests classes and the technique there was to set some sort of allowAutoRedirect property to false. If this is along the right lines, can anyone tell me the correct alternative for the HttpClient class?

This post has info on the above allowAutoRedirect concept I mean

Else, how might I get this method to return 301s rather than 200s for Urls I know to be genuine 301s?

Community
  • 1
  • 1
Gga
  • 4,311
  • 14
  • 39
  • 74
  • How do you know that the exception means that the server is unreachable? – John Saunders Feb 06 '13 at 14:58
  • I don't, but that's the best my abilities will allow for the mean time. – Gga Feb 06 '13 at 14:59
  • Do your abilities permit you to display the exception somewhere, by outputting `hre.ToString()`? – John Saunders Feb 06 '13 at 14:59
  • Haha, well clearly not. No good shout. It was more of a catch all approach for the mean time but I will further dissect the exceptions and implement proper handling. – Gga Feb 06 '13 at 15:01

1 Answers1

82

I have found that the way to do this is by creating an instance of HttpClientHandler and passing it in the constructor of HttpClient

public static async void makeRequest(int row, string url)
{
    string result;
    Stopwatch sw = new Stopwatch(); sw.Start();

    // added here
    HttpClientHandler httpClientHandler = new HttpClientHandler();
    httpClientHandler.AllowAutoRedirect = false;

    try
    {
        // passed in here
        using (HttpClient client = new HttpClient(httpClientHandler))
        {

        }

See here for more info.

Richard
  • 106,783
  • 21
  • 203
  • 265
Gga
  • 4,311
  • 14
  • 39
  • 74
  • But settings AllowAutoRedirect to flase means you have to manually handle each 3XX cases. There is no way to only alter 301 case. – MuiBienCarlota Mar 05 '15 at 13:12
  • In fact, you have to handle manually 301, 302, 303 and 307. – MuiBienCarlota Mar 05 '15 at 15:34
  • 2
    By the way, you wrapped HttpClient in a using statement, but the HttpClientHandler needs to be disposed too. – aholmes Jul 16 '15 at 02:39
  • 12
    FYI - you should not create a new instance of `HttpClient` for each request. This will lead to performance issues at scale. See [this guidance](https://github.com/mspnp/performance-optimization/blob/master/ImproperInstantiation/docs/ImproperInstantiation.md) from Microsoft patterns & practices. – Matt Johnson-Pint Oct 04 '16 at 17:58
  • 1
    @MattJohnson That link is now a 404. I think this is (now) : https://learn.microsoft.com/en-gb/azure/architecture/antipatterns/improper-instantiation/ – Richard Jul 10 '17 at 05:34