Не удается поймать пользовательские ошибки Java на клиенте WCF
Проблема похожа на этот вопрос: поддерживает ли WCF FaultException
Сложно объяснить это, но здесь это идет:
Из нового клиента 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 и увидеть код и описание.
Спасибо за любые мысли, вложенные в этот или любые дальнейшие комментарии.
/ Бьорн