I made a WCF Service with wsHttpBinding that uses asp.net membership provider for authentication. I can able to host the service on Server successfully. But my problem is wiered. (I can able see the .svc and wsdl files in browser irrespective of the domain) I can able to consume the service only from my machine or any other machine in the same domain. If I try to access the service from some other domain through the application(windows appl.). It is giving me the error message :-
"The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state"
Stack Trace:
Server stack trace:
at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
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 System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
at System.ServiceModel.ClientBase1.System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
at System.ServiceModel.ClientBase1.Close()
at System.ServiceModel.ClientBase`1.System.IDisposable.Dispose()
at AOLICWindows.Forms.SynchronizeTest.btnRegistration_Click(Object sender, EventArgs e)
wsHttpBinding defaults to using Windows credentials for authentication, which is fine as long as you are on the same domain, or on domain with full trust relationships.
The error message seems to point to a timeout - maybe you need to tweak those. Once an exception happens on your server which is not handled properly and turned into a SOAP fault, then the channel (the connection between client and server) is "faulted", e.g. it goes into a state of error, and cannot be used anymore. All you can do is abort the channel (you can't even close it anymore at that point), and re-create it from scratch.
Or maybe this timeout happens because you have wrapped your client proxy's usage into a using(......) {......} block? That's usually a great idea - but not in the case of a WCF client proxy.
The problem occurs because of the fact that once a channel is faulted, you can't even close it anymore. If you wrap your client proxy usage into a using() statement, when something goes bad on the server and isn't handled properly, the channel will fault, and at the end of the using() block, the .NET runtime tries to close it, which then throw another exception since the channel is faulted....
So for WCF clients, the recommended best practice is something like this:
YourClientProxy proxy = new YourClientProxy();
try
{
... use it
proxy.Close();
}
catch(TimeoutException exception)
{
proxy.Abort();
}
catch(CommunicationException exception)
{
proxy.Abort();
}
Marc
Related
I have a Web API (ASP.NET Core 3.0, IIS 6.2) on Windows Server 2012 R2. When it's making an HTTPS request to an external SOAP API, I get a responce with code 500 after 20 seconds. My API wrote in a log:
The operation timed out
Tail of an exception stack trace:
at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)\r\n at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)\r\n at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)\r\n at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.<>c__DisplayClass1_0.b__0(IAsyncResult asyncResult)\r\n--- End of stack trace from previous location where exception was thrown ---
I repeat my API's request from the same server to external one by SoapUI. It's successfull after 2-3 seconds. Also my Web API works from my another server.
Unfortunatelly, I don't know how to get a reason of the problem. Can you give me any idea, please?
I found a solution. I just updated nuget packages System.ServiceModel.* from 4.4.0 and WCF requests work appropriately now.
https://github.com/dotnet/wcf/issues/2368
Background:
I've noticed that in my WCF services, when I throw an Exception (a plain old exception), the client channel enters the faulted state and has to be aborted and re-created before I can make another call on that channel. That's fine. That's how it's intended. I get it. So I just call abort() and re-create if I need to make another call.
However, faulting of the client channel only happens when I'm using a binding that has security enabled. When I use basicHttpBinding, I can get an exception on the client, and then keep using the ServiceClient object without it telling me it's in "the faulted state".
Also, when I turn off security on wsHttpBinding or netTcpBinding, I can re-use the channel after an Exception.
Question:
What is is about a binding's security that makes it fault the channel so it's unusable?
This is because with Security, you are setting up a secure session. When you throw out of that session, the channel enters the faulted state and you have to abort it and create a new one. With BasicHttpBinding, there's no session going on.
When throwing a FaultException from a WCF service, is there a way it can be thrown without faulting the actual connection? I'm looking to prevent an action for a particular method, but don't want to disrupt the client's connection (just return saying "you can't do this action right now, and here's why"). Or, is the required paradigm to recreate a new proxy in the .NET consuming app (in the case of .NET)
If you throw a FaultException then the client will get an exception but should be able to carry on using the same connection. If you let any other kind of exception out of the service (without having a Custom Error Handler in place) then it will fault the channel
Are you using .NET 4.0, can you use WebFaultException to return an HTTP status code with the appropriate error reason?
Is there a way in a WCF service to catch a client timeout I need to run some special logic on a client timeout.
I have not found any sources indicating a WCF service can check if a client timeout through service side Error Handling, Etc... if you require more information let me know.
Anything that needs to be cleaned up in your service, should be cleaned up regardless of whether there was a client timeout, a client disconnection, or an exception in the service.
Do your cleanup in the finally block of a try/finally, or, if you clean up by calling the Dispose method of an IDisposable object, then use using blocks.
I am migrating a WPF application to Silverlight. My WPF application accesses a Web Service using BackgroundWorker. If there is any error while accessing the web service I get an extensive error message in my callback, for example
There was no endpoint listening at http://localhost:8080/services/registration
that could accept the message. This is often caused by an incorrect address or
SOAP action. See InnerException, if present, for more details.
In my Silverlight application, I am accessing the same web service asynchronously and now my error messages are not very useful, for example:
The remote server returned an error: NotFound.
The web service has not changed - I can see the faults coming from the server on Fiddler. So the question is how can I get more detailed error messages on the Silverlight client.
My callback in Silverlight application looks like this (I am accessing the error message from e.Error.Message):
private void AuthenticateUserCallback(object sender, AuthenticateUserCompletedEventArgs e)
{
if (e.Error != null)
{
this.StatusMessage = e.Error.Message;
}
...
}
This is limitation with Browser stack due to which SL cannot access the complete exception message. Look at MSDN article here
The approach is to wrap exception into meaningful faults (which means client will always get HTTP OK 200) and perform custom exception handling on the client side.