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.
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;
}
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.
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;
}
}
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.
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);
}