私は、Yahoo!の株式記号を検索する簡単なプログラムをビジュアルC#2005で作成しています。 Finance、履歴データをダウンロードし、指定されたティッカーシンボルの価格履歴をプロットします。
データを取得するために必要な正確なURLを知っており、ユーザーが既存のティッカーシンボル(またはYahoo! Financeのデータを含む少なくとも1つ)を入力すると、完全に機能します。ただし、ユーザーがティッカーシンボルを作成すると、プログラムが存在しないWebページからデータをプルしようとするため、ランタイムエラーが発生します。
WebClientクラスを使用し、DownloadString関数を使用しています。 WebClientクラスの他のすべてのメンバー関数を調べましたが、URLをテストするために使用できるものは見当たりませんでした。
これどうやってするの?
「GET」ではなく 「HEAD」 リクエストを発行できますか?
(編集)-笑! 前にこれを行った !;担当者収集の非難を避けるためにwikiに変更されました。したがって、コンテンツをダウンロードするコストなしで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
の周りに配置します。エラーなし?それが存在します...
C#2.0(VS2005)の場合:
private bool headOnly;
public bool HeadOnly {
get {return headOnly;}
set {headOnly = value;}
}
そして
using(WebClient client = new MyClient())
{
// code as before
}
このソリューションの別の実装は次のとおりです。
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;
}
}
From: http://www.dotnetthoughts.net/2009/10/14/how-to-check-remote-file-exists-using-c/
これらのソリューションはかなり優れていますが、200 OK以外のステータスコードがあることを忘れています。これは、ステータス監視などの実稼働環境で使用したソリューションです。
ターゲットページにURLリダイレクトまたはその他の条件がある場合、このメソッドを使用して戻り値はtrueになります。また、GetResponse()は例外をスローするため、StatusCodeを取得できません。例外をトラップして、ProtocolErrorを確認する必要があります。
400または500のステータスコードはfalseを返します。他のすべてはtrueを返します。このコードは、特定のステータスコードのニーズに合わせて簡単に変更できます。
/// <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;
}
あなたの質問を正しく理解したら、次のような小さな方法を使用して、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;
上記のコードをメソッドでラップし、それを使用して検証を実行できます。これがあなたが尋ねていた質問に答えることを望みます。
これを試してください(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");
別のオプションがあります
public static bool UrlIsValid(string url)
{
bool br = false;
try {
IPHostEntry ipHost = Dns.Resolve(url);
br = true;
}
catch (SocketException se) {
br = false;
}
return br;
}
このソリューションは簡単に理解できるようです:
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 ;
}
uRLが有効かどうかを判断するより簡単な方法があります。
if (Uri.IsWellFormedUriString(uriString, UriKind.RelativeOrAbsolute))
{
//...
}
Webサーバーは、リクエストの結果を示すHTTPステータスコードで応答します。 200(場合によっては202)は成功を意味し、404-見つからないなど( here を参照)。 URLのサーバーアドレス部分が正しく、ソケットタイムアウトが発生していないと仮定すると、例外はHTTPステータスコードが200以外であることを伝える可能性が高いです。例外のクラスを確認し、例外が実行されるかHTTPステータスコード。
IIRC-問題の呼び出しはWebExceptionまたは子孫をスローします。クラス名を確認してどのクラスかを確認し、条件をトラップするためにtryブロックで呼び出しをラップします。
すでに与えられた例に続いて、私は言うでしょう、このような使用で応答をラップすることもベストプラクティスです
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;
}
}
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");`
}
私はいつも例外の処理がずっと遅いことを発見しました。
おそらく、それほど集中的でない方法は、より良い、より速い結果をもたらすでしょうか?
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"));