4

I am trying to get the URL of a page using HttpClient. I've previously only used HttpWebRequest, but I need to make this an async method. In the code below, myUri always returns null which results in throwing an exception when I try to handle it later on.

Is the location header the wrong thing to be using?

        string myUrl = "http://www.example.com/"; 
        Uri myUri= new Uri(myUrl);
        using (HttpClient client = new HttpClient())
        using (HttpResponseMessage response = await client.GetAsync(myUri))
        {
            if (response.IsSuccessStatusCode)
            {
                myUri= response.Headers.Location;
                Debug.WriteLine("True "+ myUri);
            } 
            else {
                Debug.WriteLine("False " + myUri);
            }
        }
3
  • 1
    response.Headers.Location refers to a redirect. It won't always be set Commented Jan 26, 2016 at 23:44
  • @Rob OK thanks I'm trying to get redirected URLs anyway but it always seems to return null. Commented Jan 26, 2016 at 23:45
  • 1
    Are you trying to get the final URL to which the page redirects? Commented Jan 26, 2016 at 23:48

3 Answers 3

7

It's because HttpClient will automatically follows redirects. If you need the URL a page redirects to, you need to stop it from automatically following:

Change your code to the following:

string myUrl = "http://www.example.com/"; 
Uri myUri= new Uri(myUrl);

HttpClientHandler httpClientHandler = new HttpClientHandler();
httpClientHandler.AllowAutoRedirect = false;

using (HttpClient client = new HttpClient(httpClientHandler))
Sign up to request clarification or add additional context in comments.

Comments

4

Here is an async way to resolve the final redirect URL:

public static async Task<string> ResolveFinalRedirectAsync(string url) 
{ 
  try
  { 
    var req = WebRequest.CreateHttp(url); 
    req.AllowAutoRedirect = true;
    var res = await req.GetResponseAsync(); 
    return res.ResponseUri.AbsoluteUri; 
  } 
  catch
  { 
    Console.WriteLine("Couldn't resolve '{0}'", url); 
  } 
  return null; 
} 

Comments

2

See @Rob's answer about AllowAutoRedirect.

Once you do that, note

The line

if (response.IsSuccessStatusCode)

evaluates to false if you receive a HTTP 301 redirect (anything outside of the 200-299 range)

A value that indicates if the HTTP response was successful. true if HttpStatusCode was in the Successful range (200-299); otherwise false.

(source)

OK thanks I'm trying to get redirected URLs anyway

If you prevent automatically following redirects, you will get an HTTP response in the 3xx range for the redirect. Your check for valid codes will have to be modified accordingly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.