2015-06-30 3 views
6

Я пытаюсь отправить исключения из WCF наиболее универсальным способом. Вот что я получил:Правильный способ исключения исключений из WCF

[ServiceContract] 
interface IContract 
{ 
    [OperationContract] 
    void Foo(); 
} 

class ContractImplementation: IContract 
{ 
    public void Foo() 
    { 
     try 
     { 
      Bar(); 
     } 
     catch (Exception ex) 
     { 
      throw new FaultException<Exception>(ex, ex.Message); 
     } 
    } 
} 

Исключение, которое на самом деле выходит из Bar является:

[Serializable] 
class MyException : Exception 
{ 
    // serialization constructors 
} 

ошибка, что я вижу в протоколирования на стороне сервера ФОС:

Тип 'MyException' с данными название контракта 'MyException: http://schemas.datacontract.org/2004/07/MyException' не ожидается. Подумайте об использовании DataContractResolver или добавьте любые типы , не известные статически в список известных типов - например, с помощью атрибута KnownTypeAttribute или путем добавления их в список известных типов, которые передаются DataContractSerializer .

То, что я пытался до сих пор:

[ServiceKnownType(typeof(MyException))] 
[ServiceContract] 
interface IContract 
{ 
    [FaultContract(typeof(MyException))] 
    [OperationContract] 
    void Foo(); 
} 

Но не повезло.

+0

Не может быть, потому что вы бросаете новый FaultException (ex, ex.Message); а не «бросать новое исключение FaultException (например, ex.Message);» ? Кроме того, исключение TDetail of FaultException не должно быть исключением – hazzik

+0

@hazzik: Я помещаю фактическое исключение в Деталь, потому что я хочу изменить его на стороне клиента. – Tudor

ответ

2

Во-первых, в MyException удалите наследование из Exception и сделайте его общедоступным.

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

[FaultContractAttribute(
     typeof(MyException), 
     Action = "", 
     Name = "MyException", 
     Namespace = "YourNamespace")] 
    [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults = true)] 
    [OperationContract] 
    void Foo() 

Наконец, вы можете бросить свое исключение, как это:

throw new FaultException<MyException> 
      (
       new MyException(ex.Message), 
       new FaultReason("Description of your Fault") 

      ); 

Надеется, что это помогает.

+0

Спасибо, это сработало. К сожалению, мне кажется, что я должен иметь явные инструкции 'throw' для каждого типа, который наследуется от моего суперкласса исключения. – Tudor

0

Во-первых - извинения, я бы предпочел опубликовать это как комментарий, а не как ответ. Как относительный нуб, я не могу!

В данной статье рассматриваются в приличном уровне детализации, как ретранслировать детали исключения обратно: http://www.codeproject.com/Articles/799258/WCF-Exception-FaultException-FaultContract

AFAIK, вы не можете на самом деле пройти само исключение обратно клиенту, как исключение не является SOAP-совместимым. Также подумайте, может ли передача всего исключения нарушить безопасность вашего кода.

+0

Если вы читаете сообщение OP, они уже пытались реализовать исключение FaultException. Статья, с которой вы связались, заключается в том, как реализовать исключение FaultException. Даже в качестве комментария это не помогает ОП. Если у вас есть предложение относительно того, как они должны изменить свой код, отправьте его. Мне жаль, что я был суровым, и я знаю, что вы пытаетесь быть полезным, но это не очень хороший ответ. –

+0

Кроме того, вы не помните правильный пароль. Бросать исключение Fault и позволять ему возвращаться к вызывающему абоненту * точно *, как вы должны * сделать это. Затем вызывающий абонент может поймать и обработать исключение, естественно, в своем вызывающем коде. –

+0

@ Тома Редферн, я думаю, это немного грубо. Принятый ответ отбрасывает исключение сбоя с типом пользователей. Этот тип не наследуется от Exception и, следовательно, не является Исключением как таковым.Это именно то, что предлагает статья. Кроме того, я не предполагал, что пользователь не должен проходить через исключение FaultException, но только этот передающий пакет полная информация об исключении может быть не очень хорошей идеей. – GinjaNinja