C # ¿Cómo puedo verificar si existe una URL / es válida?

Estoy haciendo un progtwig simple en visual c # 2005 que busca un símbolo de stock en Yahoo! Financie, descarga los datos históricos y luego traza el historial de precios para el símbolo de cotización especificado.

Conozco la URL exacta que necesito para adquirir los datos, y si el usuario ingresa un símbolo de cotización existente (o al menos uno con datos en Yahoo! Finanzas) funciona perfectamente bien. Sin embargo, tengo un error de tiempo de ejecución si el usuario crea un símbolo de cotización, ya que el progtwig intenta extraer datos de una página web inexistente.

Estoy usando la clase WebClient y usando la función DownloadString. Revisé todas las otras funciones miembro de la clase WebClient, pero no vi nada que pudiera usar para probar una URL.

¿Cómo puedo hacer esto?

¿Podría emitir una solicitud “HEAD” en lugar de un “GET”?

(editar) – ¡lol! ¡Parece que he hecho esto antes ! cambiado a wiki para evitar acusaciones de rep-garnering. Entonces, para probar una URL sin el costo de descargar el contenido:

// using MyClient from linked post using(var client = new MyClient()) { client.HeadOnly = true; // fine, no content downloaded string s1 = client.DownloadString("http://google.com"); // throws 404 string s2 = client.DownloadString("http://google.com/silly"); } 

try catch el DownloadString para verificar si hay errores; ¿No hay error? Existe…


Con C # 2.0 (VS2005):

 private bool headOnly; public bool HeadOnly { get {return headOnly;} set {headOnly = value;} } 

y

 using(WebClient client = new MyClient()) { // code as before } 

Aquí hay otra implementación de esta solución:

 using System.Net; /// /// Checks the file exists or not. /// /// The URL of the remote file. /// True : If the file exits, False if file not exists private bool RemoteFileExists(string url) { try { //Creating the HttpWebRequest HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; //Setting the Request method HEAD, you can also use GET too. request.Method = "HEAD"; //Getting the Web Response. HttpWebResponse response = request.GetResponse() as HttpWebResponse; //Returns TRUE if the Status code == 200 response.Close(); return (response.StatusCode == HttpStatusCode.OK); } catch { //Any exception will returns false. return false; } } 

De: http://www.dotnetthoughts.net/2009/10/14/how-to-check-remote-file-exists-using-c/

Estas soluciones son bastante buenas, pero están olvidando que puede haber otros códigos de estado que 200 OK. Esta es una solución que he usado en entornos de producción para el monitoreo de estado y demás.

Si hay una redirección de URL o alguna otra condición en la página de destino, la devolución será verdadera utilizando este método. Además, GetResponse () emitirá una excepción y, por lo tanto, no obtendrá un código de estado para ello. Debe atrapar la excepción y comprobar si hay un error de protocolo.

Cualquier código de estado 400 o 500 devolverá falso. Todos los demás regresan verdad. Este código se modifica fácilmente para adaptarse a sus necesidades de códigos de estado específicos.

 ///  /// This method will check a url to see that it does not return server or protocol errors ///  /// The path to check ///  public bool UrlIsValid(string url) { try { HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest; request.Timeout = 5000; //set the timeout to 5 seconds to keep the user from waiting too long for the page to load request.Method = "HEAD"; //Get only the header information -- no need to download any content using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { int statusCode = (int)response.StatusCode; if (statusCode >= 100 && statusCode < 400) //Good requests { return true; } else if (statusCode >= 500 && statusCode < = 510) //Server Errors { //log.Warn(String.Format("The remote server has thrown an internal error. Url is not valid: {0}", url)); Debug.WriteLine(String.Format("The remote server has thrown an internal error. Url is not valid: {0}", url)); return false; } } } catch (WebException ex) { if (ex.Status == WebExceptionStatus.ProtocolError) //400 errors { return false; } else { log.Warn(String.Format("Unhandled status [{0}] returned for url: {1}", ex.Status, url), ex); } } catch (Exception ex) { log.Error(String.Format("Could not test url {0}.", url), ex); } return false; } 

Si entiendo su pregunta correctamente, podría usar un método pequeño como este para darle los resultados de su prueba de URL:

 WebRequest webRequest = WebRequest.Create(url); WebResponse webResponse; try { webResponse = webRequest.GetResponse(); } catch //If exception thrown then couldn't get response from address { return 0; } return 1; 

Puede envolver el código anterior en un método y usarlo para realizar la validación. Espero que esto responda la pregunta que estabas haciendo.

Pruebe esto (asegúrese de usar System.Net):

 public bool checkWebsite(string URL) { try { WebClient wc = new WebClient(); string HTMLSource = wc.DownloadString(URL); return true; } catch (Exception) { return false; } } 

Cuando se llama a la función checkWebsite (), intenta obtener el código fuente de la URL pasada. Si obtiene el código fuente, devuelve verdadero. Si no, devuelve falso.

Ejemplo de código:

 //The checkWebsite command will return true: bool websiteExists = this.checkWebsite("https://www.google.com"); //The checkWebsite command will return false: bool websiteExists = this.checkWebsite("https://www.thisisnotarealwebsite.com/fakepage.html"); 

Aquí hay otra opción

 public static bool UrlIsValid(string url) { bool br = false; try { IPHostEntry ipHost = Dns.Resolve(url); br = true; } catch (SocketException se) { br = false; } return br; } 

Esta solución parece fácil de seguir:

 public static bool isValidURL(string url) { WebRequest webRequest = WebRequest.Create(url); WebResponse webResponse; try { webResponse = webRequest.GetResponse(); } catch //If exception thrown then couldn't get response from address { return false ; } return true ; } 

Tengo una manera más simple de determinar si una URL es válida.

 if (Uri.IsWellFormedUriString(uriString, UriKind.RelativeOrAbsolute)) { //... } 

Los servidores web responden con un código de estado HTTP que indica el resultado de la solicitud, p. Ej. 200 (a veces 202) significa éxito, 404 – no se encuentra, etc. (ver aquí ). Suponiendo que la dirección del servidor parte de la URL es correcta y no está obteniendo un tiempo de espera del socket, la excepción probablemente le indique que el código de estado HTTP no era 200. Sugeriría verificar la clase de la excepción y ver si la excepción conlleva el código de estado HTTP.

IIRC: la llamada en cuestión arroja una WebException o un descendiente. Compruebe el nombre de la clase para ver cuál y envuelva la llamada en un bloque de prueba para atrapar la condición.

Siguiendo con los ejemplos ya presentados, diría que es una buena práctica también envolver la respuesta en un uso como este

  public bool IsValidUrl(string url) { try { var request = WebRequest.Create(url); request.Timeout = 5000; request.Method = "HEAD"; using (var response = (HttpWebResponse)request.GetResponse()) { response.Close(); return response.StatusCode == HttpStatusCode.OK; } } catch (Exception exception) { return false; } } 

Siempre he encontrado que las excepciones son mucho más lentas de manejar.

¿Tal vez una forma menos intensiva generaría un resultado mejor y más rápido?

 public bool IsValidUri(Uri uri) { using (HttpClient Client = new HttpClient()) { HttpResponseMessage result = Client.GetAsync(uri).Result; HttpStatusCode StatusCode = result.StatusCode; switch (StatusCode) { case HttpStatusCode.Accepted: return true; case HttpStatusCode.OK: return true; default: return false; } } } 

Entonces solo usa:

 IsValidUri(new Uri("http://www.google.com/censorship_algorithm")); 
 WebRequest request = WebRequest.Create("http://www.google.com"); try { request.GetResponse(); } catch //If exception thrown then couldn't get response from address { MessageBox.Show("The URL is incorrect");` }