2012-03-05 2 views
2

У меня есть службы WCF, где я подхватить SqlException, а затем вернуть его в качестве FaultException как этотWCF FaultException <SqlException> перехватило CommunicationException

throw new FaultException<SqlException>(...); 

А на стороне клиента, я ловя как этот

catch (FaultException<SqlException> e) 
{ 
    // do something with exception 
} 
catch (FaultException<Exception> e) 
{ 
    // do something with exception 
} 

Я не верю, что у меня есть проблема в моем web.config на стороне службы или app.config на стороне клиента (WinForm клиента), как я могу поймать FaultException<ArgumentException>, FaultException<Exception> и т.д., но не FaultException<SqlException>

я не нашел ничего о том, что я не могу передать SQLExceptions вниз к клиенту, мой контракт операции правильно сконфигурированный с вещами, как [FaultContract(typeof(SqlException))] и [FaultContract(typeof(Exception))]

Кто-нибудь видел это или знаете, что я не могу (или, возможно, нужно что-то делать) пропускать ошибки типа SqlException до клиента? Спасибо.

+0

жалком Абт предыдущий комментарий. Я не думаю, что вы можете отправить stacktrace обратно клиенту. – Asdfg

ответ

3

throw new FaultException<Exception> на самом деле не так, как предполагается использовать систему отказа WCF. Указанный тип сериализуется по проводке в элементе <Detail> ошибки SOAP. Обычно этот тип является классом контракта данных WCF, который вы пишете, например.

[DataContract] 
public class MyFault { 
    [DataMember] 
    public string Message {get; set;} 
} 

throw new FaultException<Exception> случается работать, потому что Exception является [Serializable] и DataContractSerializer способен обрабатывать [Serializable] типов, а также [DataContract] типов.

Однако существуют серьезные ограничения для этого подхода. DataContractSerializer не обрабатывает типы [Serializable] очень хорошо. Только поля примитивных типов (string, int и т. Д.) Будут переданы правильно. Это всего лишь ОК для очень простого типа исключения, но для сложного типа, такого как SqlException, это недостаточно.

Мое предложенное решение: создайте свой собственный выделенный договор данных, чтобы передать данные из SqlException, которые вам нужны, а затем бросьте это вместо этого. Фактически, делайте это для всех типов исключений, это более безопасная и лучшая практика. Я использую Enterprise Library Exception Shielding, чтобы обрабатывать это автоматически. Все, что передается обратно клиенту, - это одно значение GUID, определяющее данные об ошибках в журнале сервера.

В качестве альтернативы, если вы решили перейти по маршруту исключения, см. this detailed article.

0

Я столкнулся с этой проблемой, потому что у меня была точка останова в неправильном месте. Я удалил все точки останова с Debug..Delete all Breakpoints (Ctrl-Alt-F9), и все исключения CommunicationException исчезли и были заменены правильными сообщениями, возвращающимися назад.

Да, время ожидания составляет 60 секунд, так что это никогда не должно было произойти, так что это было, вероятно, какой-то загадочный артефакт Visual Studio 2012.

Смежные вопросы