WCF - ошибки/исключения или сообщения

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

Ответы

Ответ 1

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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