59

I know I can locally, on my filesystem, check if a file exists:

if(File.Exists(path))

Can I check at a particular remote URL?

2
  • See also here for mixing WebClient and HEAD in a single answer: stackoverflow.com/questions/153451#156750 Commented Dec 30, 2009 at 13:26
  • Marc, why would using a custom class be better in this case? Later on you even suggest on using try / catch. Commented Aug 17, 2012 at 21:00

11 Answers 11

97

If you're attempting to verify the existence of a web resource, I would recommend using the HttpWebRequest class. This will allow you to send a HEAD request to the URL in question. Only the response headers will be returned, even if the resource exists.

var url = "http://www.domain.com/image.png";
HttpWebResponse response = null;
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "HEAD";


try
{
    response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
    /* A WebException will be thrown if the status of the response is not `200 OK` */
}
finally
{
    // Don't forget to close your response.
    if (response != null)
    {
        response.Close();
    }
}

Of course, if you want to download the resource if it exists it would most likely be more efficient to send a GET request instead (by not setting the Method property to "HEAD", or by using the WebClient class).

Sign up to request clarification or add additional context in comments.

3 Comments

I'd recommend checking for a 404 rather than just any 'ol error code. If it's a 500, for example, then it might be that the "file" exists, but that the server encountered (a perhaps temporary) error when servicing the request. To check for 404s, make sure to cast ex.Response to HttpWebResponse, and then you can compare StatusCode to HttpStatusCode.NotFound.
I'm surprised I'm the first one to note that response should be Disposed!
If you use a using on response = (HttpWebResponse)request.GetResponse(); it will be disposed of automatically.
20

If you want to just copy & paste Justin's code and get a method to use, here's how I've implemented it:

using System.Net;

public class MyClass {
    static public bool URLExists (string url) {
        bool result = false;

        WebRequest webRequest = WebRequest.Create(url);
        webRequest.Timeout = 1200; // miliseconds
        webRequest.Method = "HEAD";

        HttpWebResponse response = null;

        try {
            response = (HttpWebResponse)webRequest.GetResponse();
            result = true;
        } catch (WebException webException) {
            Debug.Log(url +" doesn't exist: "+ webException.Message);
        } finally {
            if (response != null) {
                response.Close();
            }
        }

        return result;
    }
}

I'll keep his observation:

If you want to download the resource, and it exists, it would be more efficient to send a GET request instead by not setting the Method property to "HEAD" or by using the WebClient class.

4 Comments

Don't forget to close the response.
You're right, @MrDustpan. But I wonder if we still need to close it since we never assigned it anywhere...
I disagree about closing the response, since when the object is disposed it is also closed (compare referencesource.microsoft.com/#System/net/System/Net/… ).
wrapping the best answer into a method, it then becomes the better answer
12

Below is a simplified version of the code:

public bool URLExists(string url)
{
    bool result = true;

    WebRequest webRequest = WebRequest.Create(url);
    webRequest.Timeout = 1200; // miliseconds
    webRequest.Method = "HEAD";

    try
    {
        webRequest.GetResponse();
    }
    catch
    {
        result = false;
    }

    return result;
}

Comments

4

If you are using a unc path or a mapped drive, this will work fine.

If you are using a web address (http, ftp etc) you are better off using WebClient - you will get a WebException if it doesn't exist.

Comments

4
public static bool UrlExists(string file)
    {
        bool exists = false;
        HttpWebResponse response = null;
        var request = (HttpWebRequest)WebRequest.Create(file);
        request.Method = "HEAD";
        request.Timeout = 5000; // milliseconds
        request.AllowAutoRedirect = false;

        try
        {
            response = (HttpWebResponse)request.GetResponse();
            exists = response.StatusCode == HttpStatusCode.OK;
        }
        catch
        {
            exists = false;
        }
        finally
        {
            // close your response.
            if (response != null)
                response.Close();
        }
        return exists;
    }

1 Comment

Allows you to check webpage or any file located on a web server. Even if it tries to redirects to a 404 page.
4

I had the same problem to solve in asp.net core, I've solved with HttpClient

private async Task<bool> isFileExist(string url)
        {
            using (HttpClient client = new HttpClient())
            {
                var restponse = await client.GetAsync(url);

               return restponse.StatusCode == System.Net.HttpStatusCode.OK;
            }
        }

Comments

2

My version:

    public bool IsUrlExist(string url, int timeOutMs = 1000)
    {
        WebRequest webRequest = WebRequest.Create(url);
        webRequest.Method = "HEAD";
        webRequest.Timeout = timeOutMs;

        try
        {
            var response = webRequest.GetResponse();
            /* response is `200 OK` */
            response.Close();
        }
        catch
        {
            /* Any other response */
            return false;
        }

        return true;
    }

Comments

1

WebRequest will waiting long time(ignore the timeout user set) because not set proxy, so I change to use RestSharp to do this.

var client = new RestClient(url);
var request = new RestRequest(Method.HEAD);

 request.Timeout = 5000;
 var response = client.Execute(request);
 result = response.StatusCode == HttpStatusCode.OK;

Comments

1

Thanks for all answers. And I would like to add my implementation which includes default state when we get errors, for specific cases like mine.

private bool HTTP_URLExists(String vstrURL, bool vResErrorDefault = false, int vTimeOut = 1200)
{
   bool vResult = false;
   WebRequest webRequest = WebRequest.Create(vstrURL);
   webRequest.Timeout = vTimeOut; // miliseconds
   webRequest.Method = "HEAD";
   HttpWebResponse response = null;
   try
   {
      response = (HttpWebResponse)webRequest.GetResponse();
      if (response.StatusCode == HttpStatusCode.OK) vResult = true;
      else if (response.StatusCode == HttpStatusCode.NotFound) vResult = false;
      else vResult = vResErrorDefault;
   }
       catch (WebException ex)
           {
           
              if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
              {
                  var resp01 = (HttpWebResponse)ex.Response;
                  if (resp01.StatusCode == HttpStatusCode.NotFound)
                  {
                      vResult = false;
                  }
                  else
                     {
                         vResult = vResErrorDefault;
                     }
                 }
                 else
                     {
                         vResult = vResErrorDefault;
                     }
                 }
           finally
           {
               // Don't forget to close your response.
               if (response != null)
               {
                   response.Close();
               }
           }
           return vResult;
}

Comments

0

Anoter version with define timeout :

public bool URLExists(string url,int timeout = 5000)
{
    ...
    webRequest.Timeout = timeout; // miliseconds
    ...
}

Comments

0

This works for me:

bool HaveFile(string url)
        {
            try
            {
                using (WebClient webClient = new WebClient())
                {
                    webClient.DownloadString(url);
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        } 

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.