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

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

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

如何有效地测试我是否能够从Web服务获得响应?

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

为了监视我们的Web服务连接,我创建了一个具有CheckService()方法的IMonitoredService接口。 每个Web服务的包装类实现此方法以在Web服务上调用无害方法并报告服务是否已启动。 这允许监视任何数量的服务,而不需要知道服务细节的负责监视的代码。

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

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

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; } 

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

我想,有两种情况:

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

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

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

如果它是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", "")); // 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错误快速引发exception。 该示例中相当长的超时是允许慢速WCF服务在长时间不活动之后或iisreset之后重新启动。 如果客户端需要响应,则可以使用较短的超时轮询,直到服务可用。