Не удается поймать пользовательские ошибки Java на клиенте WCF

Проблема похожа на этот вопрос: поддерживает ли WCF FaultException взаимодействие с отказом веб-службы Java. Однако в моем случае пользовательская ошибка действительно возвращается из службы.

Сложно объяснить это, но здесь это идет:

Из нового клиента WCF я вызываю существующий веб-сервис Java (который хорошо работал в течение многих лет с другими типами клиентов). Служба XSD определяет одну пользовательскую ошибку ServiceFault:

<xs:complexType name="ServiceFault">
        <xs:annotation>
            <xs:documentation>On service error</xs:documentation>
        </xs:annotation>
        <xs:all>
            <xs:element name="ErrorCode" type="xs:string"/>
            <xs:element name="ErrorDescription" type="xs:string"/>
        </xs:all>
    </xs:complexType>

Этот ServiceFault используется для всех более специфических пользовательских сбоев (например, MyMethodFault), поэтому все они получают свойства ErrorCode и ErrorDescription, например:

<xs:element name="MyMethodFault" type="ServiceFault">
    <xs:annotation>
        <xs:documentation>On error in MyMethod</xs:documentation>
    </xs:annotation>
</xs:element>

Далее определяются WSDL-сообщения об ошибках, например:

<wsdl:message name="MyMethodFault">
<wsdl:part element="tns:MyMethodFault " name="MyMethodFault">
</wsdl:part>

И, наконец, операции определяются с этими ошибками, например:

<wsdl:fault message="tns:MyMethodFault" name="MyMethodFault">

Выглядит хорошо для меня, пока. А во время выполнения сервис аккуратно возвращает ошибки в подробном SOAP-теге, например так:

<ns2:MyMethodFault xmlns:ns2="urn:salessystem:entity:MyService:v1.0">
<ns2:ErrorCode>1000</ns2:ErrorCode>
<ns2:ErrorDescription>TheErrorDescr</ns2:ErrorDescription>
</ns2:MyMethodFault>

Однако SvcUtil не генерировал более специфичные пользовательские ошибки, только ServiceFault. Это единственное упоминание MyMethodFault в справочнике услуг:

[OperationContractAttribute(Action = "", ReplyAction = "*")]
[FaultContractAttribute(typeof(sale...ServiceFault), Action="", Name="MyMethodFault")]        
[ServiceKnownTypeAttribute(typeof(ServiceFault))]
MyMethodResponse MyMethod(MyMethodRequest1 request);

Итак, вот проблема:

Так как MyMethodFault не существует, я не могу поймать FaultException<MyMethodFault>. И более того, WCF не будет отображать конкретную ошибку, такую ​​как MyMethodFault, в ServiceFault во время выполнения, поэтому исключения типа FaultException<ServiceFault> никогда не поймали. Следовательно, я никогда не получаю описание ошибки.

Я делаю что-то не так или мне нужно настроить WSDL или использование SvcUtil?

Надеюсь, что кто-нибудь может понять вопрос вообще:P

Спасибо, Бьёрн

1 ответ

Решение

Иногда маленький отпуск - это все, что тебе нужно. Задача решена:

SvcUtil сгенерировал не один, а два типа C# для общего пользовательского сбоя ServiceFault. Другой был расположен глубже в иерархии пространства имен. И попытка поймать эту другую ошибку работает просто отлично. Все более специфические пользовательские ошибки (которые происходят от ServiceFault в XSD) обнаруживаются здесь, и я могу видеть код ошибки и описание ошибки. Это все, что мне нужно прямо сейчас.

Однако у меня до сих пор нет типов C#, созданных для более специфических пользовательских сбоев, таких как MyMethodFault, описанных в XSD. Но, возможно, я не должен!

Что я не смог описать в приведенных выше примерах кода, так это то, что конкретный сбой XML-файла MyMethodFault в ответе SOAP находится внутри тега Detail возвращенного сбоя:

<SOAP-ENV:Fault>
  <faultcode>SOAP-ENV:Server</faultcode>
  <faultstring xml:lang="en">ServiceException</faultstring>
  <detail>
    <ns2:MyMethodFault xmlns:ns2="urn:salessystem:entity:MyService:v1.0">
      <ns2:ErrorCode>1000</ns2:ErrorCode>
      <ns2:ErrorDescription>My+Error+Description</ns2:ErrorDescription>
    </ns2:UcsAgreemenFault>
  </detail>
</SOAP-ENV:Fault>

Эта ошибка отображается в "базовом" ServiceFault в моем try/catch. В приведенном выше SOAP вы можете четко видеть тип или имя конкретной ошибки. Однако я не знаю, как заполучить этот тип / имя при обнаружении исключения. Все, что я вижу, это ErrorCode и ErrorDescription. Тем не менее, все хорошо, пока я могу поймать ServiceFault и увидеть код и описание.

Спасибо за любые мысли, вложенные в этот или любые дальнейшие комментарии.

/ Бьорн

Другие вопросы по тегам