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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/330496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 23:28:32  来源:igfitidea点击:

How do I test connectivity to an unknown web service in C#?

c#web-services

提问by RichieACC

I'm busy writing a class that monitors the status of RAS connections. I need to test to make sure that the connection is not only connected, but also that it can communicate with my web service. Since this class will be used in many future projects, I'd like a way to test the connection to the webservice without knowing anything about it.

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

I was thinking of passing the URL to the class so that it at least knows where to find it. Pinging the server is not a sufficient test. It is possible for the server to be available, but the service to be offline.

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

How can I effectively test that I'm able to get a response from the web service?

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

采纳答案by g .

You are right that pinging the server isn't sufficient. The server can be up, but the web service unavailable due to a number of reasons.

你是对的,ping 服务器是不够的。服务器可以正常运行,但由于多种原因导致 Web 服务不可用。

To monitor our web service connections, I created a IMonitoredService interface that has a method CheckService(). The wrapper class for each web service implements this method to call an innocuous method on the web service and reports if the service is up or not. This allows any number of services to be monitored with out the code responsible for the monitoring knowing the details of the service.

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

If you know a bit about what the web service will return from accessing the URL directly, you could try just using the URL. For example, Microsoft's asmx file returns a summary of the web service. Other implementations may behave differently though.

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

回答by TcKs

The tip: create a interface/baseclass with method "InvokeWithSomeParameters". The meaning of "SomeParameters" should be a "parameters which 100% does not affect any important state".

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

I think, there are 2 cases:

我认为,有两种情况:

  • Simple webservice, which does not affect any data on server. For example: GetCurrentTime(). This web service can be called without parameters.
  • Complex webservice, which can affect some daty on server. For example: Enlist pending tasks. You fill-up parameter with values which 100% throws a exception (resp. does not change affect pending tasks), if you got some exception like "ArgumentException", you know the service is alive.
  • 简单的网络服务,不影响服务器上的任何数据。例如:GetCurrentTime()。可以不带参数调用此 Web 服务。
  • 复杂的网络服务,可能会影响服务器上的某些日期。例如:登记挂起的任务。你用 100% 抛出异常的值填充参数(相应地不会改变影响挂起的任务),如果你得到一些像“ArgumentException”这样的异常,你就知道服务是活动的。

I don't think, this is most clear solution, but it should works.

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

回答by Thomas Bratt

How about opening a TCP/IP connection to the port used by the webservice? If the connection works, the RAS connection, the rest of the network and the host are all working. The webservice is almost certainly running too.

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

回答by Blue Toque

You could try the following which tests the web site's existence:

您可以尝试以下测试网站是否存在的方法:

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

回答by Berend Engelbrecht

If it is a Microsoft SOAP or WCF service and service discovery is allowed, you can request the web page serviceurl + "?disco" for discovery. If what is returned is a valid XML document , you know the service is alive and well. A non-Microsoft SOAP service that does not allow ?disco will probably return valid XML too.

如果是微软的 SOAP 或 WCF 服务,并且允许服务发现,则可以请求网页 serviceurl + "?disco" 进行发现。如果返回的是一个有效的 XML 文档,您就知道该服务是有效的。不允许使用 ?disco 的非 Microsoft SOAP 服务也可能返回有效的 XML。

Sample code:

示例代码:

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

If the web server is present, but the service does not exist, an exception will be raised quickly for the 404 error. The fairly long time-out in the example is to allow a slow WCF service to restart after a long period of inactivity or after iisreset. If the client needs to be responsive, you could poll with a shorter timeout until the service is available.

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