С# Как проверить, существует ли URL-адрес?
Я делаю простую программу на Visual С# 2005, которая просматривает символ акции на Yahoo! Финансы, загружает исторические данные, а затем отображает историю цен для указанного символа тикера.
Я знаю точный URL, который мне нужен для получения данных, и если пользователь вводит существующий символ тикера (или, по крайней мере, один с данными в Yahoo! Finance), он работает отлично. Тем не менее, у меня есть ошибка во время выполнения, если пользователь составляет символ тикера, поскольку программа пытается извлечь данные с несуществующей веб-страницы.
Я использую класс WebClient и использую функцию DownloadString. Я просмотрел все другие функции-члены класса WebClient, но не видел ничего, что мог бы использовать для проверки URL-адреса.
Как я могу это сделать?
Ответы
Ответ 1
Вы можете запросить "HEAD" вместо "GET"?
(править) - lol! Похоже, что я сделал это раньше!; изменен на wiki, чтобы избежать обвинений в rep-garnering. Итак, чтобы протестировать URL-адрес без затрат на загрузку контента:
// 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
вокруг DownloadString
проверить наличие ошибок; Нет ошибки? Он существует...
С С# 2.0 (VS2005):
private bool headOnly;
public bool HeadOnly {
get {return headOnly;}
set {headOnly = value;}
}
и
using(WebClient client = new MyClient())
{
// code as before
}
Ответ 2
Вот еще одна реализация этого решения:
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;
}
}
От: http://www.dotnetthoughts.net/2009/10/14/how-to-check-remote-file-exists-using-c/
Ответ 3
Эти решения довольно хороши, но они забывают, что могут быть другие коды статуса, чем 200 OK. Это решение, которое я использовал в производственных средах для мониторинга состояния и т.д.
Если на целевой странице есть перенаправление URL или какое-либо другое условие, возврат будет истинным с использованием этого метода. Кроме того, GetResponse() будет генерировать исключение, и, следовательно, вы не получите для него StatusCode. Вам нужно заманить исключение и проверить протокол ProtocolError.
Любой код состояния 400 или 500 возвращает false. Все остальные верны. Этот код легко модифицируется в соответствии с вашими потребностями для определенных кодов состояния.
/// <summary>
/// This method will check a url to see that it does not return server or protocol errors
/// </summary>
/// <param name="url">The path to check</param>
/// <returns></returns>
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;
}
Ответ 4
Если я правильно понял ваш вопрос, вы можете использовать небольшой метод, подобный этому, чтобы дать вам результаты вашего теста 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;
Вы можете перенести вышеуказанный код в метод и использовать его для выполнения проверки. Надеюсь, это ответ на вопрос, который вы задавали.
Ответ 5
Попробуйте (убедитесь, что вы используете System.Net):
public bool checkWebsite(string URL) {
try {
WebClient wc = new WebClient();
string HTMLSource = wc.DownloadString(URL);
return true;
}
catch (Exception) {
return false;
}
}
Когда функция checkWebsite() вызывается, она пытается получить исходный код
URL-адрес, переданный в него. Если он получает исходный код, он возвращает true. Если не,
он возвращает false.
Пример кода:
//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");
Ответ 6
Это решение выглядит легко:
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 ;
}
Ответ 7
Вот еще один вариант
public static bool UrlIsValid(string url)
{
bool br = false;
try {
IPHostEntry ipHost = Dns.Resolve(url);
br = true;
}
catch (SocketException se) {
br = false;
}
return br;
}
Ответ 8
У меня есть более простой способ определения погоды. URL-адрес действителен.
if (Uri.IsWellFormedUriString(uriString, UriKind.RelativeOrAbsolute))
{
//...
}
Ответ 9
Веб-серверы отвечают кодом состояния HTTP, указывающим результат запроса, например. 200 (иногда 202) означает успех, 404 - не найден и т.д. (См. здесь). Предполагая, что адрес URL-адреса сервера указан правильно, и вы не получаете тайм-аут сокета, исключение, скорее всего, говорит вам, что код статуса HTTP был отличным от 200. Я бы предложил проверить класс исключения и посмотреть, не содержит ли это исключение код статуса HTTP.
IIRC - вызываемый вызов вызывает исключение WebException или потомок. Проверьте имя класса, чтобы увидеть, какой из них и завершите вызов в блоке try, чтобы уловить условие.
Ответ 10
Следуя приведенным выше примерам, я бы сказал, что лучше всего также обернуть ответ при использовании, подобном этому
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;
}
}
Ответ 11
Я всегда находил, что Исключения намного медленнее, чем нужно обрабатывать.
Возможно, менее интенсивный способ мог бы получить более быстрый, быстрый результат?
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;
}
}
}
Затем просто используйте:
IsValidUri(new Uri("http://www.google.com/censorship_algorithm"));
Ответ 12
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");'
}