2009-09-17 3 views
2

Мы подключаемся к веб-службе, а сообщение о неисправности, которое мы получаем, не является десериализацией (вообще), и никакой версией класса, который я могу make будет десериализоваться правильно. Мы не контролируем серверную сторону вещей. Сервер не разрешает обнаружение, поэтому добавление WSDL в конец URL-адреса конечной точки приводит к ошибке, а не к WSDL.Множество пространств имен в сообщении о неисправности мыла, вызывающем десериализацию исключения FaultException для отказа

[Скрипач] [1] показывает сообщение о неисправности возвращается выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?> 
<soapenv:Envelope xmlns:eGov="http://eGov.gov" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Body> 
    <soapenv:Fault> 
    <faultcode>Client</faultcode> 
    <faultstring/> 
     <detail> 
     <eGov:eGov2Exception> 
      <eGov:ErrorClassification>SOME_ERROR</eGov:ErrorClassification> 
      <eGov:ErrorCode>SOME_ERROR_CODE</eGov:ErrorCode> 
      <eGov:ErrorMessage>Your request was unsuccessful. blah blah blah.</eGov:ErrorMessage> 
     </eGov:eGov2Exception> 
     </detail> 
    </soapenv:Fault> 
    </soapenv:Body> 
</soapenv:Envelope> 

Но ни один класс мы сделали (пытаясь xsd.exe, SvcUtil и другие, включая код мы написали с нуля) может десериализации, когда мы пытаемся поймать его:

catch (FaultException<eGov2ExceptionType> exp) 
    { 
    // Never stops here. 
    } 
catch (FaultException<AllOtherAttemptedClasses> exp) 
    { 
    // Never stops here. 
    } 
catch (SoapException se) 
    { 
    // Never stops here. 
    } 
catch (FaultException exp) 
    { 
    //Always gets caught here. 
    } 

только базовый FaultException улов будет вызван, то есть мы теряем содержимое FaultMessage отправки. Некоторые из классов, которые я написал, будут сериализоваться очень близко к образцу выше, но не могут десериализовать его, поэтому наше подозрение в том, что проблема с пространством имен.

Вопросы:

1 - Как бы вы написать это?

2 - Это распространенная ошибка/проблема с WCF?

[1]: http://www.fiddler2.com/fiddler2/ Скрипач

+0

Возможный обман http://stackoverflow.com/questions/4140030/c-sharp-wcf-catch-fault-exceptions-of-base-type http: // stackoverflow.com/questions/9463802/wcf-custom-fault-exception-not-catch-correct-in-client – Ruskin

ответ

4

Что мы закончили делать, так это отказаться от попытки поймать Fault и передать его обратно в SOAP-канал. Вместо этого мы создали специальное исключение и подключили MessageInspector, чтобы следить за ошибками и бросать его в качестве исключения.

Соответствующая часть (продезинфицировать) Код:

public void AfterReceiveReply(ref Message reply, object correlationState) 
    { 
     if (reply.IsFault) 
     { 
      XmlDictionaryReader xdr = reply.GetReaderAtBodyContents(); 
      XNode xn = XDocument.ReadFrom(xdr); 
      string s = xn.ToString(); 
      XDocument xd = XDocument.Parse(s); 
      XNamespace nsSoap = "http://schemas.xmlsoap.org/soap/envelope/"; 
      XNamespace ns = "http://eGov.gov"; 
      XElement xErrorClass = xd.Element(nsSoap + "Fault").Element("detail").Element(ns + "eGov2Exception").Element(ns + "RequestErrorClassification"); 
      XElement xErrorCode = xd.Element(nsSoap + "Fault").Element("detail").Element(ns + "eGov2Exception").Element(ns + "RequestErrorCode"); 
      XElement xErrorMessage = xd.Element(nsSoap + "Fault").Element("detail").Element(ns + "eGov2Exception").Element(ns + "RequestErrorMessage"); 

      throw new eGovException(xErrorClass.Value, xErrorCode.Value, xErrorMessage.Value); 
     } 
    } 

Основное применение затем использует:

поймать (eGovException ех)
{
// Обрабатывает исключение здесь.
}

Слишком много времени было потрачено впустую, пытаясь исправить пространства имен. Спасибо за ответ.

1

Один из способов справиться с этим, если сериализации не удается полностью заключается в использовании OoperationContract с использованием в качестве Message типа ввода и вывода. Таким образом, вы можете вручную проанализировать XML, когда Iffault == true или использовать GetBody(), чтобы получить регулярное содержимое, если ошибка не возникла.

1

Прежде всего, если вы не можете получить WSDL у людей, которые создали этот веб-сервис, то у них нет бизнеса с веб-сервисом на основе SOAP. Правильный WSDL решит вашу проблему, независимо от того, используется ли «WSDL» или нет.

Во-вторых, пожалуйста, напишите код класса eGov2ExceptionType. Я подозреваю, что на нем нет пространства имен http://eGov.gov.

+0

WSDL были отправлены по почте «квалифицированным партнерам», одним из которых мы являемся. В понедельник я отправлю код самого близкого класса, который я сделал. – Tangurena

+0

Если у вас есть WSDL, вы можете предоставить его svcutil.exe и получить то, что вам нужно. Попробуйте это и посмотрите, генерирует ли svcutil сообщения об ошибках или предупреждения. Если ни один не отображается, посмотрите в сгенерированные классы - иногда предупреждения отображаются в виде комментариев в сгенерированном коде. –

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

  • Нет связанных вопросов^_^