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, если это необходимо.
Информация об исключении должна быть записана в центральную службу регистрации и не передана обратно из службы.
Мысли? Комментарии? Идеи? Предложения?
Некоторые дополнительные разъяснения по моему вопросу
Проблема, с которой я сталкиваюсь с контрактами по вине, - это общение бизнес-правил
Мол, если кто-то входит в систему, и его учетная запись заблокирована, как мне сообщить об этом? Их логин явно не удается, но не удается по причине "Аккаунт заблокирован".
Я тоже:
А) используйте логическое значение, сбросьте Fault с заблокированной учетной записью сообщения
Б) вернуть AuthenticatedDTO с соответствующей информацией
3 ответа
Это, однако, несет накладные расходы, так как создание исключений в.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. Я отправлю сегодня вечером с дополнительной информацией. (Извините, это слабый ответ)