从C#应用程序测试网站是否可用

54

我正在寻找从C#应用程序中测试网站是否存在的最佳方法。

背景

我的应用程序由一个Winforms UI、一个后端WCF服务和一个网站组成,用于向UI和其他使用者发布内容。为防止UI启动时由于缺少WCF服务或网站宕机而无法正常工作,我已经添加了应用程序启动检查来确保所有内容都处于运行状态。

该应用程序是用C#、.NET 3.5和Visual Studio 2008编写的。

当前解决方案

目前,我正在向网站上的测试页面发送网络请求,该页面将测试网站并显示结果。

WebRequest request = WebRequest.Create("http://localhost/myContentSite/test.aspx");
WebResponse response = request.GetResponse();

我假设如果在此调用期间没有异常抛出,那么一切都很好,UI 可以启动。

问题

这是最简单、正确的方法,还是在 C# 中有其他秘密调用,或者有更好的方法可以做到这一点。

7个回答

94
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response == null || response.StatusCode != HttpStatusCode.OK)

如@Yanga所提到的,HttpClient现在可能是更常用的方法。

HttpClient client = new HttpClient();
var checkingResponse = await client.GetAsync(url);
if (!checkingResponse.IsSuccessStatusCode)
{
   return false;
}

2
这个对于任何网站都适用吗?我正在做类似的东西,但在某些网站上会出现错误,但当我在浏览器中输入URL时,它可以正常打开。 - confusedMind
2
@confusedMind 可能是服务器返回的状态码不是200 OK状态码。如果您查看HTTP状态码列表,您会注意到所有200、300 HTTP状态码都不是错误代码,因此在浏览器中仍然可以加载页面,就好像一切正常。 - clifford.duke
2
HTTP 500会抛出异常,因此现有的检查不足够。请查看以下内容以捕获异常并检查HTTP状态码:https://dev59.com/inRB5IYBdhLWcg3wLk1M。 - Overflew
好的。但是,如果请求的页面主体很大(例如:100MB <),这种方式是不合理的!获取所请求资源的头部就足以确定。 - Mohammad Afrashteh
@MohammadAfrashteh 我从未遇到过100MB的页面或任何接近这个大小的东西,但如果这对您非常重要,我认为在调用GetResponse之前设置request.Method =“HEAD”将不会返回内容。希望这可以帮到您。 - Echostorm
显示剩余2条评论

21

在使用 WebResponse 时,请确保关闭响应流,即 (.close),否则在多次执行后会挂起机器。

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sURL);
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
// your code here
response.Close();

2
Maxymus是对的,我遇到了服务器在一段时间后不响应我的问题,但添加response.Close();解决了它。 - Ricky Casavecchia
+1. 关闭响应很容易被忽视(刚刚发生在我身上)。 - Hanlet Escaño
2
我同意,但应该是:response.Close(); 注意大小写。 - Chris Spittles

10

来自CodePlex上的NDiagnostics项目...

public override bool WebSiteIsAvailable(string Url)
{
  string Message = string.Empty;
  HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(Url);

  // Set the credentials to the current user account
  request.Credentials = System.Net.CredentialCache.DefaultCredentials;
  request.Method = "GET";

  try
  {
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
      // Do nothing; we're only testing to see if we can get the response
    }
  }
  catch (WebException ex)
  {
    Message += ((Message.Length > 0) ? "\n" : "") + ex.Message;
  }

  return (Message.Length == 0);
}

2
使用 HEAD 动词可以更快。 - Lex Li
请求在All-In-One Code中添加诊断工具http://1code.codeplex.com/workitem/10118 - Kiquenet

8

我们可以使用HttpClient()来更新答案:

HttpClient Client = new HttpClient();
var result = await Client.GetAsync("https://stackoverflow.com");
int StatusCode = (int)result.StatusCode;

3
假设WCF服务和网站位于同一Web应用程序中,则可以使用“状态”WebService返回应用程序状态。你可能想要执行以下操作:
  • 测试数据库是否正常运行(连接字符串正确,服务正常运行等)
  • 测试网站是否正常工作(具体如何取决于网站)
  • 测试WCF是否正常工作(具体如何取决于实现方式)
  • 额外的好处是:如果需要支持不同的发布版本,可以在服务中返回一些版本信息。
然后,在Win.Forms应用程序中为WebService创建一个客户端。如果WS没有响应(即调用时出现异常),则网站就无法访问(类似于“一般错误”)。
如果WS有响应,您可以解析结果并确保一切正常,或者如果出现问题,则返回更多信息。

很不幸,它们不在同一个 Web 应用程序中,但这并不是太大的问题。我已经为数据库和 ORM 创建了所有测试 :) (但感谢您的建议) - FryHard
有关实际应用的示例?测试数据库、网站、WCF、版本控制 - Kiquenet

-3
您需要检查状态码是否为OK(状态码200)。

-3

解决方案来自:C#中如何检查网站是否在线?

var ping = new System.Net.NetworkInformation.Ping();

var result = ping.Send("https://www.stackoverflow.com");

if (result.Status != System.Net.NetworkInformation.IPStatus.Success)
    return;

4
这仅是对服务器发送一个ping,即检查该机器是否正在运行。它并不检查服务器在80端口上是否响应信息。 - Karlth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接