Каков наилучший подход для обработки исключений в службе WCF? - PullRequest
23 голосов
/ 08 октября 2009

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

Служба WCF подключена к SQL Server 2005 для чтения и записи данных. Это сценарий интрасети, в котором клиент должен находиться в одном домене.

Теперь могут быть сценарии, в которых служба wcf генерирует исключения:

  1. Неверный URL
  2. Служба WCF недоступна
  3. SQL Server 2005 не работает
  4. Клиент не находится в том же домене
  5. Сбой аутентификации
  6. Авторизация не удалась

и многие другие исключения.

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

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

Ответы [ 4 ]

33 голосов
/ 08 октября 2009

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

Таким образом, вы не будете "отказывать" (или разрушать) канал связи между вашим клиентом и сервером.

Еще лучшим подходом будет реализация интерфейса IErrorHandler в вашем классе обслуживания, который предоставляет способ для глобального отслеживания всех исключений по мере их возникновения и предоставления вместо этого FaultException, который совместим с SOAP.

Вы даже можете включить IErrorHandler в настраиваемое поведение, которое можно включить или отключить в конфигурации.

См. Эти статьи и сообщения в блоге для получения более подробной информации:

6 голосов
/ 08 октября 2009
  1. Создать пользовательский класс ошибок, помеченный атрибутом DataContract
  2. Отметьте метод в интерфейсе контракта на обслуживание с помощью FaultContract . То есть. [FaultContract(typeof(CustomFault))]
  3. В вашем методе обслуживания перехватите все применимые внутренние исключения и скажите FaultException . В качестве альтернативы, как упоминалось в marc_s, вы можете использовать IErrorHandler для сопоставления исключения с ошибкой.

Лично я создаю базовый класс Fault со свойством Reason и расширяю все пользовательские ошибки этого класса. Когда я хочу сбросить вину, я звоню:

throw Fault.Create<CustomFault>(new CustomFault("Boo hoo"));

Стоит также отметить, что я делаю свои классы ошибок (включая общий класс Fault) вместе со всеми другими моими службами. Однако это касается только версии службы.

Вот базовый класс Fault (для краткости я удалил проверку аргументов):

[DataContract(Namespace = XmlVersionNamespace.FaultNamespace)]
public abstract class Fault
{
    internal FaultReason Reason { get; set; }

    protected Fault(string reasonText)
    {
        Reason = new FaultReason(new FaultReasonText(reasonText, CultureInfo.CurrentUICulture));
    }

    public override string ToString()
    {
        return Reason.ToString();
    }

    internal static FaultException<TDetail> Create<TDetail>(TDetail fault) where TDetail : Fault
    {
        return new FaultException<TDetail>(fault, fault.Reason);
    }
}
2 голосов
/ 08 октября 2009

Вы можете разработать конкретные Контракты с данными о сбоях для каждого из сценариев исключений в службе WCF, чтобы вы могли обрабатывать сбой / исключение на стороне клиента соответственно.

1 голос
/ 08 октября 2009
try
{
  // Actions
}
catch (Exception ex)
{
  // Log the exception
  // Throw Fault Exception back to client
  FaultException fe = new FaultException(ex.Message, new FaultCode("Your fault code"));
  //throw fault exception back to WCF client
  throw fe;
}           
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...