WCF - ошибки / исключения по сравнению с сообщениями - PullRequest
37 голосов
/ 17 сентября 2008

В настоящее время мы ведем дискуссию о том, лучше ли перебрасывать ошибки по каналу 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, если это необходимо.

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

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

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

У меня возникла проблема с договорами о сбоях в связи с передачей бизнес-правил.

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

Я тоже:

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

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

Ответы [ 3 ]

31 голосов
/ 17 сентября 2008

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

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

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

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

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

6 голосов
/ 25 сентября 2012

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

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

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

0 голосов
/ 17 сентября 2008

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

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

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