Подтвердить что ты не робот

Каков наилучший подход для обработки исключений в службе WCF?

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

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

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

  • Недопустимый URL
  • Служба WCF отключена.
  • SQL Server 2005 не запущен
  • Клиент не находится в одном домене
  • Ошибка аутентификации
  • Ошибка авторизации

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Подробнее см. в этих статьях и блогах:

Ответ 2

  • Создайте собственный класс отказов, помеченный атрибутом DataContract
  • Отметьте метод на интерфейсе контракта на обслуживание с FaultContract. То есть. [FaultContract(typeof(CustomFault))]
  • В вашем методе обслуживания уловить любые применимые внутренние исключения и выбросить FaultException <CustomFault> . В качестве альтернативы, как указано в 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);
    }
}

Ответ 3

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

Ответ 4

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