127

我正在 Visual c# 2005 中制作一个简单的程序,用于在 Yahoo! 上查找股票代码。Finance,下载历史数据,然后绘制指定股票代码的价格历史。

我知道获取数据所需的确切 URL,如果用户输入一个现有的股票代码(或至少一个带有 Yahoo! Finance 上的数据的代码),它工作得非常好。但是,如果用户制作股票代码,我会遇到运行时错误,因为程序试图从不存在的网页中提取数据。

我正在使用 WebClient 类,并使用 DownloadString 函数。我查看了 WebClient 类的所有其他成员函数,但没有看到可以用来测试 URL 的任何东西。

我怎样才能做到这一点?

4

13 回答 13

151

这是此解决方案的另一种实现:

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/

于 2010-09-28T00:20:16.417 回答
119

您可以发出“HEAD”请求而不是“GET”吗?因此,无需下载内容即可测试 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
}
于 2009-05-29T06:38:50.750 回答
38

这些解决方案都很好,但是他们忘记了可能还有其他状态码而不是 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;
}
于 2011-08-24T17:54:47.477 回答
9

如果我正确理解您的问题,您可以使用这样的小方法为您提供 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;

您可以将上述代码包装在一个方法中并使用它来执行验证。我希望这能回答你提出的问题。

于 2009-05-29T07:07:07.837 回答
6

试试这个(确保你使用 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");
于 2016-10-01T22:07:27.697 回答
4

此解决方案似乎很容易遵循:

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 ;
}
于 2011-05-08T09:23:36.687 回答
4

我一直发现异常处理起来要慢得多。

也许一种不那么密集的方法会产生更好、更快的结果?

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"));
于 2018-03-12T07:09:16.897 回答
4
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");`
}
于 2018-06-21T08:39:32.130 回答
3

这是另一种选择

public static bool UrlIsValid(string url)
{
    bool br = false;
    try {
        IPHostEntry ipHost = Dns.Resolve(url);
        br = true;
    }
    catch (SocketException se) {
        br = false;
    }
    return br;
}
于 2012-05-01T04:43:23.277 回答
3

很多答案都比 HttpClient 旧(我认为它是在 Visual Studio 2013 中引入的)或没有 async/await 功能,所以我决定发布我自己的解决方案:

private static async Task<bool> DoesUrlExists(String url)
{
    try
    {
        using (HttpClient client = new HttpClient())
        {
            //Do only Head request to avoid download full file
            var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));

            if (response.IsSuccessStatusCode) {
                //Url is available is we have a SuccessStatusCode
                return true;
            }
            return false;
        }                
    } catch {
            return false;
    }
}

我使用HttpClient.SendAsyncwithHttpMethod.Head只发出一个头部请求,而不是下载整个文件。就像 David 和 Marc 已经说过的那样,不仅 http 200 可以,所以我IsSuccessStatusCode习惯于允许所有成功状态代码。

于 2021-11-04T07:19:56.033 回答
1

Web 服务器以指示请求结果的 HTTP 状态代码进行响应,例如 200(有时 202)表示成功,404 - 未找到等(参见此处)。假设 URL 的服务器地址部分是正确的并且您没有收到套接字超时,那么异常很可能会告诉您 HTTP 状态代码不是 200。我建议检查异常的类并查看异常是否携带HTTP 状态码。

IIRC - 有问题的调用会引发 WebException 或后代。检查类名以查看是哪一个并将调用包装在 try 块中以捕获条件。

于 2009-05-29T06:45:12.173 回答
1

我有一种更简单的方法来确定 URL 是否有效。

if (Uri.IsWellFormedUriString(uriString, UriKind.RelativeOrAbsolute))
{
   //...
}
于 2012-02-20T05:19:01.190 回答
1

继已经给出的示例之后,我想说,最好的做法是也将响应包装在这样的 using 中

    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;
        }
   }
于 2016-09-16T10:18:06.207 回答