22

What's the easiest way in .NET to check what status code a web server replies with to a GET request?

Note that I do not need the body of the response. In fact, if possible, only the header should be requested. Having said that, however, if requesting that the body of the response be omitted significantly increases the complexity of the code, receiving the body would be fine.

Also, I'm particularly interested in catching ALL the possible appropriate exceptions (System.Net.WebException, System.IO.IOException, System.Net.Sockets.SocketException, etc.), as this routine will run thousands of times a day.

foobarbarfoo
  • 369
  • 1
  • 4
  • 9

6 Answers6

29
public HttpStatusCode GetHeaders(string url)
    {
        HttpStatusCode result = default(HttpStatusCode);

        var request = HttpWebRequest.Create(url);
        request.Method = "HEAD";
        using (var response = request.GetResponse() as HttpWebResponse)
        {
            if (response != null)
            {
                result = response.StatusCode;
                response.Close();
            }
        }

        return result;
    }
Ivan Ferić
  • 4,725
  • 11
  • 37
  • 47
  • 4
    but if the URL is 404 there is an error. cannot found 404 exception – william Aug 31 '12 at 03:04
  • Actually, it is not an error. It's a regular HTTP response with the difference of status code being 404.. – Ivan Ferić Aug 31 '12 at 12:46
  • @ Ivan : So, am i supposed to use `try - catch` for 404 pages? – william Sep 11 '12 at 06:32
  • No, because they won't throw an exception. They'll just return a page with a status code 404.. – Ivan Ferić Sep 11 '12 at 12:34
  • do you mean your `var response = .......` will get a 404? But when I try it out using an extra character in the working URL the page shows an error. – william Sep 12 '12 at 01:22
  • nope, `result` will be 404. Did you try using URL you mentioned with the code or in the browser? The browser itself will probably display the error page but that's because the browser was coded that way not because 404 page is actually an error page. As aside, you can see the list of exceptions the `GetResponse()` method can throw here - http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse.aspx The only potential error that is thrown for reasons other than invalid URL is WebException if request times out (not the same as a 404 page) – Ivan Ferić Sep 12 '12 at 11:42
  • using this code for a non-existing resource gives a WebException: "The remote name could not be resolved...", **not** a HttpWebResponse with StatusCode = 404 – Alex Oct 04 '14 at 13:03
  • As I said, WebException is thrown if the request times out. This, however, might be due to server's configurations - some servers might be configured to not return 404 responses for non existing resources which is what happened in your case. In those cases, the proper thing to do is include the try catch block around using as Michael Logutov demonstrated in his answer to this question.. – Ivan Ferić Oct 06 '14 at 04:42
14

Use the HTTP method HEAD, which is the same as GET except doesn't return the body:

var request = (HttpWebRequest)WebRequest.Create("http://www.example.com");
request.Method = "HEAD";
var response = (HttpWebResponse)request.GetResponse();

// status code...
response.StatusCode;

From Section 9.4 of RFC2616:

The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification.

John Rasch
  • 62,489
  • 19
  • 106
  • 139
5

I've ended up with this method which combines Ivan Ferić's answer and with proper exceptional cases support:

public async Task<bool> IsAccessibleAsync (string url)
{
    if (url == null)
        throw new ArgumentNullException ("url");

    if (url.IndexOf (':') < 0)
        url = "http://" + url.TrimStart ('/');

    if (!Uri.IsWellFormedUriString (url, UriKind.Absolute))
        return false;

    var request = (HttpWebRequest) WebRequest.Create (url);
    request.Method = "HEAD";

    try
    {
        using (var response = await request.GetResponseAsync () as HttpWebResponse)
        {
            if (response != null && response.StatusCode == HttpStatusCode.OK)
                return true;

            return false;
        }
    }
    catch (WebException)
    {
        return false;
    }
}
Michael Logutov
  • 2,551
  • 4
  • 28
  • 32
3

If you use HttpWebRequest, it's pretty easy:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://url");
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
HttpStatusCode status = response.StatusCode;

You can surround that with a blanket catch clause, or look at the docs for WebRequest.Create and .GetResponse to see what exceptions will get thrown.

Kirk Woll
  • 76,112
  • 22
  • 180
  • 195
0

Here is what I came up with that handles 404 exceptions. There is also a test below.

public static HttpStatusCode GetUrlStatus(string url, string userAgent)
{
    HttpStatusCode result = default(HttpStatusCode);

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.UserAgent = userAgent;
    request.Method = "HEAD";

    try
    {
        using (var response = request.GetResponse() as HttpWebResponse)
        {
            if (response != null)
            {
                result = response.StatusCode;
                response.Close();
            }
        }
    }
    catch (WebException we)
    {
        result = ((HttpWebResponse)we.Response).StatusCode;
    }

    return result;
}


[Test]
public void PageNotFoundShouldReturn404()
{
    //Arrange
    HttpStatusCode expected = HttpStatusCode.NotFound;
    string userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36";

    //Act
    HttpStatusCode result = WebHelper.GetUrlStatus("http://www.kellermansoftware.com/SomePageThatDoesNotExist", userAgent);

    //Assert
    Assert.AreEqual(expected, result);
}   
Greg Finzer
  • 6,714
  • 21
  • 80
  • 125
0

WebRequest is obsolete, use HttpClient instead:

public async static Task<HttpStatusCode> GetStatusCode(string url)
{
    using var client = new HttpClient();
    var res = await client.GetAsync(url);
    return res.StatusCode;
}
neosonne
  • 136
  • 1
  • 4