Вызов веб-службы WCF - какие исключения нужно перехватить? - PullRequest
6 голосов
/ 21 марта 2011

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

try {
   client.MyWebService()
}
catch(? ex)
{
   // display friendly dialog explaining what went wrong
}

какие исключения я должен поставить вместо знака вопроса в коде?Трудно на самом деле тестировать подобные ситуации, когда все работает без сбоев, и я не контролирую внешнюю часть, поэтому некоторые знания будут оценены.

Спасибо!

Ответы [ 3 ]

6 голосов
/ 21 марта 2011

Первое, что нужно сделать, это воспользоваться преимуществом события .Faults на вашем прокси, которое вы можете подключить так:

((ICommunicationObject)client).Faulted += new EventHandler(client_Faulted);

В вашем обработчике событий client_Faulted вы можете затем повторить попытку.подключение или переключение на сервер резервного копирования, или отключение пользовательского интерфейса, регистрация ошибки или отображение там сообщения.

Очевидно, что по-прежнему хорошей практикой является также оборачивать каждый вызов в try-catch, но.Неудачное событие может позволить вам справиться с большинством проблем с каналом даже раньше.

Что касается самого исключения, вы можете заставить свой сервис выдать FaultException, который передается обратно клиенту с предоставленной вами информацией.См. Пример его использования в этой публикации блога .

Вы не получите FaultException, если сам канал отказывает (FaultException - это способ для сервера сообщать о своих внутренних ошибкахклиент).

При сбое канала вы можете получить CommunicationException или TimeoutException.

Наконец, взгляните на этот проект в Codeplex для генерации прокси WCF-обработчиков исключений,Это может дать вам более гибкий способ обработки ошибок.

1 голос
/ 14 марта 2018

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

Ответ дан C. Лоуренс Уэнам был уже очень хорош и указывает на некоторую интересную информацию, хотя ссылка на блог сломана и Codeplex теперь архивирован.

Я нашел эти статьи очень ценными:

Отправка и получение ошибок
https://docs.microsoft.com/en-us/dotnet/framework/wcf/sending-and-receiving-faults

Ожидаемые исключения
https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/expected-exceptions

И эта статья от Michèle Leroux Bustamante (очевидно, создатель Генератора прокси WCF проекта CodePlex) очень полезна:

Элегантное прокси-решение для обработки исключений
http://www.itprotoday.com/microsoft-visual-studio/elegant-exception-handling-proxy-solution

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

Просто чтобы ответить здесь явно на то, что изначально было задано, какие исключения могут быть проверены для вызова веб-службы:

string errorMessage = null;

// A class derived from System.ServiceModel.ClientBase.
MyWebService wcfClient = new MyWebService();
try
{
   wcfClient.Open();
   wcfClient.MyWebServiceMethod();
}
catch (TimeoutException timeEx)
{
   // The service operation timed out.
   errorMessage = timeEx.Message;
}
catch (FaultException<ExceptionDetail> declaredFaultEx)
{
   // An error on the service, transmitted via declared SOAP
   // fault (specified in the contract for an operation).
   errorMessage = declaredFaultEx.Detail.Message;
}
catch (FaultException unknownFaultEx)
{
   // An error on the service, transmitted via undeclared SOAP
   // fault (not specified in the contract for an operation).
   errorMessage = unknownFaultEx.Message;
}
catch (CommunicationException commEx)
{
   // A communication error in either the service or client application.
   errorMessage = commEx.Message;
}
finally
{
   if (wcfClient.State == CommunicationState.Faulted)
      wcfClient.Abort();
   else
      wcfClient.Close();
}

Как указано в статьях, важен порядок перехвата исключений, поскольку FaultException<TDetail> происходит от FaultException, а FaultException происходит от CommunicationException.

1 голос
/ 21 марта 2011

Работа клиента не в том, чтобы предоставить как можно больше деталей.Максимальная сумма, которую вы действительно должны предоставить на стороне клиента, равна сумме, которую вы получите в своем исключении.

var userName = "bob";
try 
{      
   client.MyWebService(userName);
}
catch(Exception ex)
{
   //Maybe we know WellKnownExceptions and can provide Foo advice:
   if (ex is WellKnownException)
   {
       Console.WriteLine("WellKnownException encountered, do Foo to fix Bar.");
   }
   //otherwise, this is the best you can do:
   Console.WriteLine(string.Format(
         "MyWebService call failed for {0}. Details: {1}", userName, ex));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...