Почему клиент WCF не получает ошибку SOAP как FaultException? - PullRequest
4 голосов
/ 17 февраля 2011

Я использую клиент WCF для использования веб-службы SOAP 1.2, отличной от WCF. При получении ошибки SOAP, как показано ниже, я получаю исключение ProtocolException вместо FaultException. Нет проблем с привязкой связи, и запрос успешно обрабатывается. Но я не могу получить доступ к ошибке в моем клиенте WCF. Есть идеи?

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:wsr="http://docs.oasis-open.org/wsrf/r-2" xmlns:xmime5="http://www.w3.org/2005/05/xmlmime" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:wsbf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:ns10="http://www.onvif.org/ver10/events/wsdl/PausableSubscriptionManagerBinding" xmlns:ns3="http://www.onvif.org/ver10/events/wsdl/PullPointSubscriptionBinding" xmlns:ns4="http://www.onvif.org/ver10/events/wsdl/EventBinding" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:ns5="http://www.onvif.org/ver10/events/wsdl/SubscriptionManagerBinding" xmlns:ns6="http://www.onvif.org/ver10/events/wsdl/NotificationProducerBinding" xmlns:ns7="http://www.onvif.org/ver10/events/wsdl/NotificationConsumerBinding" xmlns:ns8="http://www.onvif.org/ver10/events/wsdl/PullPointBinding" xmlns:ns9="http://www.onvif.org/ver10/events/wsdl/CreatePullPointBinding" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:ter="http://www.onvif.org/ver10/error" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <SOAP-ENV:Code>
            <SOAP-ENV:Value>SOAP-ENV:Sender</SOAP-ENV:Value>
            <SOAP-ENV:Subcode>
               <SOAP-ENV:Value>ter:InvalidArgVal</SOAP-ENV:Value>
               <SOAP-ENV:Subcode>
                  <SOAP-ENV:Value>ter:NoSource</SOAP-ENV:Value>
               </SOAP-ENV:Subcode>
            </SOAP-ENV:Subcode>
         </SOAP-ENV:Code>
         <SOAP-ENV:Reason>
            <SOAP-ENV:Text xml:lang="en">Not exist</SOAP-ENV:Text>
         </SOAP-ENV:Reason>
         <SOAP-ENV:Detail>
            <SOAP-ENV:Text xml:lang="en">The requested VideoSource does not exist.</SOAP-ENV:Text>
         </SOAP-ENV:Detail>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

System.ServiceModel.ProtocolException

"Удаленный сервер возвратил неожиданный ответ: (400) Неверный запрос.

    StackTrace  
    "Server stack trace: 
    at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory factory, WebException responseException, ChannelBinding channelBinding)
    at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
    at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
    at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
    at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
    at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
    at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
    at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

    Exception rethrown at [0]: 
    at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
    at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
    at OnvifProxy.ImagingPort.SetImagingSettings(String VideoSourceToken, ImagingSettings20 ImagingSettings, Boolean ForcePersistence)
    at OnvifProxy.ImagingPortClient.SetImagingSettings(String VideoSourceToken, ImagingSettings20 ImagingSettings, Boolean ForcePersistence) in D:\..\Proxies\OvifServices.cs:line 19005
    at Integral.Common.IPCameras.ONVIF.Services.ImagingService.SetImageSettings(String pVideoSourceToken, ImagingSettings20 pImageSettings) in D:\..\Services\ImagingService.cs:line 375"   string

Ответы [ 3 ]

0 голосов
/ 25 февраля 2011

Я думаю, что проблема у вас в том, что сервер возвращает код ответа HTTP 400.Очевидно, что тела сообщений с кодом ответа, отличным от 200, недоступны для клиента Silverlight.

Если вы управляете сервером, вы можете изменить его, отправив код ответа 200 вместо 400, но еслиу вас нет контроля над сервером, вам нужно изменить свой клиент так, чтобы он принимал коды ответов, отличные от 200.

Я нашел несколько инструкций здесь , чтобы изменить клиента на использование альтернативного HTTPстек.У меня была та же проблема, что и у вас (но с кодом ответа HTTP 500), и это решило проблему.Все, что вам нужно сделать, это добавить этот код в начале вашего приложения Silverlight (например, в конструкторе класса MainPage):

bool registerResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
0 голосов
/ 04 июня 2012

Помечен ли вызываемый метод атрибутом IsOneWay = true в сгенерированном прокси-классе?

Если это так, то нет никакого обратного канала для получения отказа SOAP, но WCF может вернуть его другим способом, и это отображается как ProtocolException.Насколько мне известно, для получения ошибки SOAP необходимо иметь IsOneWay = false.

0 голосов
/ 17 февраля 2011

Я бы рекомендовал использовать Fiddler для перехвата необработанного ответа. В этих ситуациях (взаимодействие) лучше всего полностью обойти WCF и прочитать ответное сообщение по мере его поступления «по проводам». Попытка отладить ошибку, не относящуюся к WCF, или ошибку десериализации с помощью WCF может привести только к головной боли. =)

Чаще всего взгляд на необработанный ответ укажет на проблему, как на больной палец.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...