为什么WCF客户端不接收SOAP错误作为FaultException?

为什么WCF客户端不接收SOAP错误作为FaultException?,wcf,Wcf,我正在使用WCF客户端使用非WCF SOAP 1.2 web服务。当收到如下所示的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/0

我正在使用WCF客户端使用非WCF SOAP 1.2 web服务。当收到如下所示的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>
我建议使用来截取原始响应。在这些情况下(互操作),最好完全绕过WCF,并在响应消息到达“在线”时读取响应消息。尝试通过WCF调试非WCF故障或反序列化错误只会让您头疼。=)


大多数情况下,查看原始响应会指出问题所在。

我认为您遇到的问题是因为服务器返回了400 HTTP响应代码。显然,Silverlight客户端无法访问响应代码不是200的消息体

如果您控制了服务器,则可以修改它以发送200响应代码,而不是400响应代码,但是如果您无法控制服务器,则需要修改客户端以接受200以外的响应代码

我找到了一些说明来更改客户端以使用替代HTTP堆栈。我和你有同样的问题(但是HTTP响应代码为500),这解决了这个问题。您只需在Silverlight应用程序的开头添加此代码(例如,在MainPage类的构造函数上):


正在调用的方法是否在生成的代理类中标记为IsOneWay=true属性


如果是,则没有用于接收SOAP错误的返回通道,但WCF可以通过其他方式将其返回,这显示为ProtocolException。据我所知,您需要使用IsOneWay=false来获取SOAP错误。

感谢您的回复。我确实有原始SOAP响应,我知道原因。但是,我对能够访问WCF客户端中的故障信息感兴趣。目前我不能,因为我得到的异常是一个简单的ProtocolException,表示一个400错误的请求。我以为我会得到一个例外。因此,我的问题是为什么我没有收到FaultException?如果您发布代码、XML或数据示例,请在文本编辑器中突出显示这些行,然后单击编辑器工具栏上的“代码示例”按钮(
{}
),以很好地格式化和语法突出显示它!你能发布ProtocolException的堆栈跟踪吗?在原始问题中添加了堆栈跟踪。谢谢
    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
bool registerResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);