Пользовательское исключение как деталь в исключении ошибки - PullRequest
5 голосов
/ 26 января 2010

Я пытаюсь добавить свое собственное исключение в FaultException из моей службы WCF и перехватить его в моем клиенте WCF. Однако на стороне клиента исключение перехватывается как неуниверсальное исключение FaultException, и сведения о моем пользовательском исключении теряются.

Мое пользовательское исключение:

[Serializable] public class MyCustomException : ApplicationException 
{ ... }

Вот как я это бросаю:

throw new FaultException<MyCustomException>(new MyCustomException("foo bar!"));

(Обратите внимание, что у меня есть [FaultContract (typeof (MyCustomException))]] поверх моего метода в интерфейсе)

А вот как я пытаюсь поймать это в моем клиенте:

...
catch (FaultException<MyCustomException> mcex)
{
    Console.WriteLine(mcex); 
}
 catch (FaultException fex) 
{
    Console.WriteLine(fex); 
}

Моя цель состоит в том, чтобы исключение было поймано в первом предложении catch, но в конечном итоге оно попадает во второе предложение catch.

Любопытно, что если я заменю MyCustomException на ApplicationException, то действительно FaultException будет правильно перехвачен.

Я предполагаю, что проблема в том, что MyCustomException сериализуется как Serializable (а не через DataContractSerializer), и что, возможно, мне не хватает какой-то дополнительной директивы WCF. Что-то в строке атрибута ServiceKnownType? (Хотя я пытался, но безрезультатно).

1 Ответ

3 голосов
/ 26 января 2010

Да, вы не сможете перехватить универсальное исключение FaultException, пока не укажете этот тип в качестве договора об ошибке в контракте на обслуживание:

[ServiceContract]
interface IYourService
{
   [OperationContract]
   [FaultContract(typeof(MyCustomException))]
   SomeReturnValue YourMethodCall(SomeInputValue input);
}

Только после того, как вы это сделаете, затем вы можете перехватить и обработать конкретное, типизированное FaultException в вашем клиентском коде.

См. документы MSDN по FaultException<T> этому сообщению в блоге , чтобы получить дополнительную информацию и хорошую информацию об обработке ошибок WCF.

Кроме того, я бы лично всегда украшал свои классы контрактов с ошибками атрибутом [DataContract] (и все члены, которые я хочу сериализовать с [DataMember]):

[Serializable] 
[DataContract]
public class MyCustomException : ApplicationException 
{ ... }
...