WCF — ошибки/исключения в сравнении с сообщениями

StackOverflow https://stackoverflow.com/questions/81306

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

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

Мы попытались создать универсальный объект сообщения, который можно было бы использовать в наших сервисах, и вот что у нас получилось:

public class ReturnItemDTO<T>
{
    [DataMember]
    public bool Success { get; set; }

    [DataMember]
    public string ErrorMessage { get; set; }

    [DataMember]
    public T Item { get; set; }
}

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

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

Мысли?Комментарии?Идеи?Предложения?

Некоторые дополнительные разъяснения по моему вопросу

Проблема, с которой я сталкиваюсь при использовании контрактов с ошибками, заключается в передаче бизнес-правил.

Например, если кто-то входит в систему и его учетная запись заблокирована, как мне сообщить об этом?Их вход в систему явно не удался, но он не удался по причине «Учетная запись заблокирована».

Я тоже:

А) используйте логическое значение, выдайте ошибку с заблокированной учетной записью сообщения

Б) вернуть AuthenticatedDTO с соответствующей информацией

Это было полезно?

Решение

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

Вы сериализуете и десериализуете объекты в XML и отправляете их по медленной сети.накладные расходы на создание исключения незначительны по сравнению с этим.

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

В вашем примере я бы выдал исключение UnauthorizedAccessException с сообщением «Учетная запись заблокирована».

Уточнение: Службы .NET wcf по умолчанию преобразуют исключения в FaultContracts, но вы можете изменить это поведение. MSDN:Определение и устранение ошибок в контрактах и ​​службах

Другие советы

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

result = CallMethod();
if (!result.Success) handleError();

result = CallAnotherMethod();
if (!result.Success) handleError();

result = NotAgain();
if (!result.Success) handleError();

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

try 
{
    CallMethod();
    CallAnotherMethod();
    NotAgain();
}
catch (Exception e)
{
    handleError();
}

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top