Why WCF client not receiving SOAP Fault as FaultException? - wcf

I am using a WCF client to consume a non-WCF SOAP 1.2 web service. When receiving a SOAP fault as shown below, I receive a ProtocolException instead of a FaultException. There are no problems with the communication binding and the request is being processed successfully. But I cannot access the fault error in my WCF client. Any ideas?
<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
"The remote server returned an unexpected response: (400) Bad Request.
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

I would recommend using Fiddler to intercept the raw response. In these situations (interop), it's best to bypass WCF entirely and read the response message as it arrives "on the wire." Trying to debug a non-WCF fault or a deserialization error through WCF can only give you headaches. =)
Most often, looking at the raw response will point the problem out like a sore thumb.

I think the problem you're having is because the server returns a 400 HTTP response code. Apparently the bodies of messages with a response code other than 200 are not accessible to the Silverlight client.
If you had control of the server, you could modify it to send a 200 response code instead of 400, but if you don't have control of the server, you need to modify your client to accept response codes other than 200.
I found some instructions here to change the client to use an alternative HTTP stack. I had the same problem as you (but with HTTP response code 500) and this fixed the problem. All you have to do is add this code at the beginning of your Silverlight application (for example, on the constructor for the MainPage class):
bool registerResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);

Is the method being called marked with the IsOneWay=true attribute in the generated proxy class?
If it is then there is no back channel for the SOAP fault to be received on but WCF can get it back some other way and this shows up as the ProtocolException. As far as I am aware you need to have IsOneWay=false to get a SOAP fault.

Related

SoftLayer (multiple) client responding with errors after API upgrade

I am having issues connecting to the SoftLayer Product/Orders APIs.
Endpoints: Product_Packages is dropping the connection, Product_Place_Orders is returning invalid auth. Hardware and VirtualGuests are accepting the credentials and returning the information I expect.
Either:
Invalid credentials
Connection reset by peer
I am, however, able to use the same credentials to see what machines and vlans are in the account.
Looking into this more, curl works, another client I have works still, however the SoftLayer python client stopped working overnight.
Did the API change Auth mechanisms change last night?
import SoftLayer
client = SoftLayer.create_client_from_env() # or
client = SoftLayer.create_client_from_env(endpoint_url="https://api.softlayer.com/rest/v3/")
location_groups = client.call('Location_Group_Pricing', 'getAllObjects')
Output:
Unexpected error: <class 'SoftLayer.exceptions.TransportError'>
Traceback (most recent call last):
File "list_product_options.py", line 28, in <module>
location_groups = client.call('Location_Group_Pricing', 'getAllObjects')
File "/Users/tony/alchemy/ibm-krobots/sl-tools/slcli/lib/python2.7/site-packages/SoftLayer/API.py", line 263, in call
return self.transport(request)
File "/Users/tony/alchemy/ibm-krobots/sl-tools/slcli/lib/python2.7/site-packages/SoftLayer/transports.py", line 199, in __call__
raise exceptions.TransportError(0, str(ex))
SoftLayer.exceptions.TransportError: TransportError(0): ('Connection aborted.', error(54, 'Connection reset by peer'))
catching the exception shows the following:
Unexpected error: <class 'SoftLayer.exceptions.TransportError'>
A working curl for the same endpoint:
curl https://<username>:<api_key>#api.softlayer.com/rest/v3/SoftLayer_Location_Group_Pricing/getAllObjects.json
Also verified that the Golang client works.
https://github.com/softlayer/softlayer-go
Just to point out that I am experiencing the same issue and I believe there is another post from someone else also mentioning the same transport/connection forcibly closed issue.
Worked last night, not working today. I'm changing my api key and user_name to see if it gets fixed. Note I too have multiple SL accounts. I'm swapping to my primary account API credentials to see what happens.
Here is the error
Unable to read data from the transport connection: An existing connection was fo rcibly closed by the remote host.
System.Net.WebException: The underlying connection was closed: An unexpected err or occurred on a send. --->
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the
remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.ConnectStream.WriteHeaders(Boolean async)
--- End of inner exception stack trace ---
at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequestrequest)
at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at SoftlayerAPIV2.Softlayer.Account.SoftLayer_AccountService.getAdcLoadBalancers
After talking with SoftLayer support, there was a service issue which has now been resolved.
Future Mitigation:
More extensive testing for older clients and related systems will be implemented into our Change Management guidelines to prevent this type of issue in the future.
(I like that part :)
This was an issue in Softlayer side, please try again it should be fixed now.
Regards
We don't have any report about issues for that, and I'm able to use SoftLayer_Product_Order service, could you provide your request(s)? for further assistance
How often have you been getting this issue?
Did you have success with those request before?

Silverlight - WCF error

I have a problem consuming a WCF service through a silver light application, the problem suddenly happened today, the same piece of code was running successfully 1 month ago,
I got the following exception:
{System.ServiceModel.ProtocolException: The content type multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="uuid:22bb2c0b-5a1b-498d-9539-a19fa401d509+id=6";start-info="text/xml" of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 626 bytes of the response were: '
--uuid:22bb2c0b-5a1b-498d-9539-a19fa401d509+id=6
Content-ID: <http://tempuri.org/0>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><LargeImageResponse xmlns="http://tempuri.org/"><LargeImageResult xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><a:int>1</a:int><a:int>2</a:int><a:int>3</a:int><a:int>4</a:int></LargeImageResult></LargeImageResponse></s:Body></s:Envelope>
--uuid:22bb2c0b-5a1b-498d-9539-a19fa401d509+id=6--
'.
at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
at AbdenTestSilverlight.FileIndexingService.FileIndexingServiceClient.FileIndexingServiceClientChannel.EndLargeImage(IAsyncResult result)
at AbdenTestSilverlight.FileIndexingService.FileIndexingServiceClient.AbdenTestSilverlight.FileIndexingService.IFileIndexingService.EndLargeImage(IAsyncResult result)
at AbdenTestSilverlight.FileIndexingService.FileIndexingServiceClient.OnEndLargeImage(IAsyncResult result)
at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)}
Content-Type: application/xop+xml; suggests that the wcf service is configured to use MTOM encoding on the server which is not supported by Silverlight.
I am not sure how this could have worked earlier unless there has been a change in the endpoint recently causing this error.

WCF Exception Marshalling and InnerException

I'm using NetDataContractSerializer to serialize exceptions over WCF. When I get NHibernateADOException (which is unknown for Client) I got FaultException. Unfortunatelly this cause that I lose inner exception message. Is there any way to deserialize unknown exception (or any other type) to specified known type or is there any other to resolve that problem?
You want to set includeExceptionDetailsInFaults to true on the service behavior.
See this question:
WCF IncludeExceptionDetailInFaults programmatically?
You can set this in web.config to return the exception:
<serviceDebug includeExceptionDetailInFaults="true"/>
This tag must be placed within the serviceBehavior tag, usually like this:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Example of detailed infomation:
Server stack trace: em
System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime
operation, ProxyRpc& rpc) em
System.ServiceModel.Channels.ServiceChannel.Call(String action,
Boolean oneway, ProxyOperationRuntime operation, Object[] ins,
Object[] outs, TimeSpan timeout) em
System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage
methodCall, ProxyOperationRuntime operation) em
System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage
message)
Exception rethrown at [0]: em
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage
reqMsg, IMessage retMsg) em
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
msgData, Int32 type) em
IMyService.GetDataOperation(RequestObterBeneficiario
request) em
MyServiceClient.GetDataOpration(RequestData
request)
This will return to the client detailed information. During development this can help out, but when your service goes to production, you will no longer keep this because your service can send sensitive data, like your database name or configuration.

Input string is not in the correct format at the same time every day

Built a client app that polls the WCF service hosted on IIS7 at timed intervals. I cannot for the life of me understand why I get "Input string is not in the correct format" error at the exact same minute every day, i.e. 4:50am. Checked Event Viewer, nothing there... Is it the SQL Server, VM, network or...?
Here's the error and the StackTrace:
Input string was not in a correct format.
Server stack trace: at
System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message
reply, MessageFault fault, String action, MessageVersion version,
FaultConverter faultConverter) at
System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime
operation, ProxyRpc& rpc) at
System.ServiceModel.Channels.ServiceChannel.Call(String action,
Boolean oneway, ProxyOperationRuntime operation, Object[] ins,
Object[] outs, TimeSpan timeout) 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
MyApplication.GenericService.IGenericService.GetCommands(String
fileName, CompanyCredentials credentials, String sequence) at
MyApplication.GenericService.GenericServiceClient.GetCommands(String
fileName, CompanyCredentials credentials, String sequence) at
MyApplication.ApplicationClass.RunCommands(String sequence)
A few things that you could check:
Are you sending a date time as a string, and there is a diffence in the time format betweem the macines?
Is recycling of app pool run just before 4:50 so that the first call after recyling allways fails
How are the credentials being sent? Have the credentials expired?

Access Denied Error for a method in web service

I have a webservice that works perfectly from localhost but when I hosted it on the testing server I get an error on one of the methods. I am using wsHttp Binding. everything else works fine on the client side except for this method. This is the error that I am getting
client error:
System.ServiceModel.Security.SecurityAccessDeniedException: Access is denied.
Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Server error:
namespace.Service Error: 10001 : Error occurred in methodname().
System.Security.SecurityException: The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security.
at System.Diagnostics.EventLog.FindSourceRegistration(String source, String machineName, Boolean readOnly)
at System.Diagnostics.EventLog.SourceExists(String source, String machineName)
at System.Diagnostics.EventLog.VerifyAndCreateSource(String sourceName, String currentMachineName)
at System.Diagnostics.EventLog.WriteEvent(EventInstance instance, Byte[] data, Object[] values)
at System.Diagnostics.EventLog.WriteEvent(EventInstance instance, Object[] values)
at System.Diagnostics.EventLogTraceListener.TraceEvent(TraceEventCache eventCache, String source, TraceEventType severity, Int32 id, String format, Object[] args)
at System.Diagnostics.TraceSource.TraceEvent(TraceEventType eventType, Int32 id, String format, Object[] args)
at AutoWatch.Entity.WcfService.TrackingService.UpdateIncidentStatusHistory(Int64 incidentId, String status, String username, String comment, Boolean SuspectFaultyUnit) in C:\..servicename.cs:line 566
at AutoWatch.Entity.WcfService.TrackingService.GetNewIncidentMessage(String username) in C:\..servicename.cs:line 444
The Zone of the assembly that failed was:
MyComputer
I added in the error I am getting on the server.
Is it possible I am getting this error because the service cannot write to the event log?
Please help.
Ensure that account running your process where the service is hosted has access rights to the database. For example in case of IIS the account running the application pool where the service is hosted must have login to database server and it must have permissions to do all necessary operations in your database.
Edit:
The server stack trace looks quite straightforward. You have a problem with writing to Windows Event Log! It cannot find source you requested and it doesn't have permission to create it.
I got the same error when I tried to use the following statement in a Web Method of a WCF Service:
string myTypeName = typeof(ErrorHandlerBehavior).AssemblyQualifiedName;
where ErrorHandlerBehavior derives from BehaviorExtensionElement.
The line works well when I test the service on my localhost. On the web, the call of the containing method raises the Exception "Access is denied".
In this case, I guess that the cause was that my IP does not allow the creation of a BehaviourExtensionElement in a Partially Trusted environment (my service is in a shared hosting environment).
Finally, I succeded following the first mechanism described at https://learn.microsoft.com/en-us/dotnet/framework/wcf/extending/configuring-and-extending-the-runtime-with-behaviors about Service Behaviors:
"Using an attribute on the service class. When a ServiceHost is constructed, the ServiceHost implementation uses reflection to discover the set of attributes on the type of the service. If any of those attributes are implementations of IServiceBehavior, they are added to the behaviors collection on ServiceDescription. This allows those behaviors to participate in the construction of the service run time."
I just modified the derivation (no other modification required):
public class ErrorServiceBehavior : Attribute, IServiceBehavior
{ ... }
and use the class as Attribute of my service:
[ErrorServiceBehavior()]
public partial class MyService : IMyService
{...}
No other modification required. Check the original sample at How do I create a global exception handler for a WCF Services?.