Как проверить подключение к неизвестному веб-сервису в C #? - PullRequest
14 голосов
/ 01 декабря 2008

Я занят написанием класса, который отслеживает состояние соединений RAS. Мне нужно проверить, чтобы убедиться, что соединение не только подключено, но и что оно может взаимодействовать с моим веб-сервисом. Поскольку этот класс будет использоваться во многих будущих проектах, я хотел бы проверить способ подключения к веб-службе, ничего не зная об этом.

Я думал передать URL классу, чтобы он хотя бы знал, где его найти. Проверка связи с сервером не является достаточным тестом. Возможно, сервер доступен, но служба отключена.

Как эффективно проверить, что я могу получить ответ от веб-службы?

Ответы [ 5 ]

16 голосов
/ 18 июня 2009

Вы можете попробовать следующее, которое проверяет существование веб-сайта:

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;
}
7 голосов
/ 01 декабря 2008

Вы правы, что проверка сервера не достаточна. Сервер может быть включен, но веб-служба недоступна по ряду причин.

Для мониторинга наших подключений к веб-сервисам я создал интерфейс IMonitoredService, который имеет метод CheckService (). Класс-оболочка для каждого веб-сервиса реализует этот метод для вызова безобидного метода в веб-сервисе и сообщает, работает ли сервис или нет. Это позволяет осуществлять мониторинг любого количества служб без кода, отвечающего за мониторинг, зная подробности службы.

Если вы немного знаете о том, что веб-сервис вернет от прямого доступа к URL, вы можете попробовать просто использовать URL. Например, файл Microsoft asmx возвращает сводную информацию о веб-службе. Другие реализации могут вести себя по-другому.

1 голос
/ 01 декабря 2008

Совет: создайте интерфейс / базовый класс с методом "InvokeWithSomeParameters". Значение «SomeParameters» должно означать «параметры, которые на 100% не влияют на какое-либо важное состояние».

Я думаю, есть 2 случая:

  • Простой веб-сервис, который не влияет на данные на сервере. Например: GetCurrentTime (). Этот веб-сервис можно вызвать без параметров.
  • Сложный веб-сервис, который может повлиять на некоторые данные на сервере. Например: подключить отложенные задачи. Вы заполняете параметр значениями, которые на 100% выдают исключение (соответственно, это не влияет на незавершенные задачи), если вы получили какое-то исключение, например, «ArgumentException», вы знаете, что сервис работает.

Не думаю, что это наиболее понятное решение, но оно должно работать.

0 голосов
/ 14 марта 2014

Если это служба Microsoft SOAP или WCF, и обнаружение службы разрешено, вы можете запросить обнаружение на веб-странице serviceurl + "? Disco". Если то, что возвращается, является действительным XML-документом, вы знаете, что сервис жив и здоров. Служба SOAP не Microsoft, которая не разрешает? Disco, вероятно, также вернет действительный 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;
    }

Если веб-сервер присутствует, но служба не существует, для ошибки 404 будет быстро создано исключение. Довольно длительный тайм-аут в этом примере состоит в том, чтобы позволить медленной службе WCF перезапуститься после длительного периода бездействия или после iisreset. Если клиент должен реагировать, вы можете опрашивать с более коротким таймаутом, пока сервис не станет доступным.

0 голосов
/ 02 декабря 2008

Как насчет открытия соединения TCP / IP с портом, используемым веб-сервисом? Если соединение работает, соединение RAS, остальная сеть и хост все работают. Веб-сервис тоже почти наверняка работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...