如何在C#中测试与未知Web服务的连接?

时间:2008-12-01 10:46:42

标签: c# web-services

我正在忙着编写一个监视RAS连接状态的类。我需要进行测试以确保连接不仅已连接,而且还可以与我的Web服务进行通信。由于这个类将在未来的许多项目中使用,我想要一种方法来测试与webservice的连接,而不需要了解它。

我正在考虑将URL传递给类,以便它至少知道在哪里找到它。 Ping服务器不是一个充分的测试。服务器可以使用,但服务可以脱机。

如何有效地测试我是否能够从网络服务获得回复?

5 个答案:

答案 0 :(得分:16)

您可以尝试以下测试网站的存在:

public static bool ServiceExists(
    string url, 
    bool throwExceptions, 
    out string errorMessage)
{
    try
    {
        errorMessage = string.Empty;

        // try accessing the web service directly via it's URL
        HttpWebRequest request = 
            WebRequest.Create(url) as HttpWebRequest;
        request.Timeout = 30000;

        using (HttpWebResponse response = 
                   request.GetResponse() as HttpWebResponse)
        {
            if (response.StatusCode != HttpStatusCode.OK)
                throw new Exception("Error locating web service");
        }

        // try getting the WSDL?
        // asmx lets you put "?wsdl" to make sure the URL is a web service
        // could parse and validate WSDL here

    }
    catch (WebException ex)
    {   
        // decompose 400- codes here if you like
        errorMessage = 
            string.Format("Error testing connection to web service at" + 
                          " \"{0}\":\r\n{1}", url, ex);
        Trace.TraceError(errorMessage);
        if (throwExceptions)
            throw new Exception(errorMessage, ex);
    }   
    catch (Exception ex)
    {
        errorMessage = 
            string.Format("Error testing connection to web service at " + 
                          "\"{0}\":\r\n{1}", url, ex);
        Trace.TraceError(errorMessage);
       if (throwExceptions)
            throw new Exception(errorMessage, ex);
        return false;
    }

    return true;
}

答案 1 :(得分:7)

你是对的,ping服务器是不够的。服务器可能已启动,但由于多种原因,Web服务不可用。

为了监控我们的Web服务连接,我创建了一个具有CheckService()方法的IMonitoredService接口。每个Web服务的包装类实现此方法以在Web服务上调用无害方法并报告服务是否已启动。这样就可以监控任何数量的服务,而无需负责监控的代码,了解服务的详细信息。

如果您对通过直接访问网址返回的Web服务有所了解,可以尝试使用该URL。例如,Microsoft的asmx文件返回Web服务的摘要。其他实现可能表现不同。

答案 2 :(得分:1)

提示:使用方法“InvokeWithSomeParameters”创建一个接口/基类。 “SomeParameters”的含义应该是“100%不影响任何重要状态的参数”。

我认为,有两种情况:

  • 简单的web服务,不会影响服务器上的任何数据。例如:GetCurrentTime()。可以在不带参数的情况下调用此Web服务。
  • 复杂的Web服务,可能会影响服务器上的某些数据。例如:登记待处理的任务。您使用100%抛出异常的值填充参数(分别不会影响待处理的任务),如果您遇到类似“ArgumentException”的异常,则表示该服务处于活动状态。

我不认为,这是最明确的解决方案,但它应该有效。

答案 3 :(得分:0)

如何打开与Web服务使用的端口的TCP / IP连接?如果连接正常,则RAS连接,网络的其余部分和主机都在工作。网络服务几乎肯定也在运行。

答案 4 :(得分:0)

如果它是Microsoft SOAP或WCF服务并且允许服务发现,您可以请求网页serviceurl +"?disco"发现。如果返回的是有效的XML文档,那么您就知道该服务还活着。不允许使用?disco的非Microsoft SOAP服务也可能会返回有效的XML。

示例代码:

    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "?disco");
    request.ClientCertificates.Add(
      new X509Certificate2(@"c:\mycertpath\mycert.pfx", "<privatekeypassword>")); // If server requires client certificate
    request.Timeout = 300000; // 5 minutes
    using (WebResponse response = request.GetResponse())
    using (Stream stream = response.GetResponseStream())
    using (StreamReader sr = new StreamReader(stream, Encoding.UTF8))
    {
      XmlDocument xd = new XmlDocument();
      xd.LoadXml(sr.ReadToEnd());
      return xd.DocumentElement.ChildNodes.Count > 0;
    }

如果Web服务器存在,但该服务不存在,则会针对404错误快速引发异常。该示例中相当长的超时是允许慢速WCF服务在长时间不活动之后或在iisreset之后重新启动。如果客户端需要响应,您可以使用较短的超时轮询,直到服务可用。