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. Я отправлю сообщение сегодня вечером с дополнительной информацией. (Извините, это слабый ответ)