I keep getting this error after I throw an error in WCF Service:
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
The error is thrown by service using
throw new FaultException<DatabaseFault>(new DatabaseFault(e.Message));
How can I handle this, in a way that doesn't need to restart both the client and the service each time?
I'm using WCF 4.0, C#.
Edit 1: I use net.tcp binding for the WCF service.
Edit 2: I want an efficient way to work with WCF. It is not related to what John S says.
Edit 3: My code works. But I think it's not running like it should(the way it was designed).
This is the console application which hosts my service :
using (ServiceHost host = new ServiceHost(typeof(AuctionService)))
{
Console.WriteLine("AuctionWCF.TestHost Started");
host.AddServiceEndpoint(
typeof(IAuctionService),
new NetTcpBinding(),
"net.tcp://localhost:9000/AuctionWcfEndPoint");
host.Open();
Console.WriteLine("AuctionWCF.TestHost listens for requests");
Console.ReadLine();
}
This is the client:
AuctionService = new ChannelFactory<IAuctionService>(
new NetTcpBinding(),
new EndpointAddress("net.tcp://localhost:9000/AuctionWcfEndPoint")).CreateChannel();
Am I doing something wrong?
Do you use a ChannelFactory? If so, this answer shows an example of a ChannelFactoryManager that has worked pretty good for me.
This is a pretty good approach and this is what I wanted to discover:
http://blog.tallan.com/2009/05/06/recover-from-a-wcf-service-fault-part-2-generic-serviceclientfactory-class/
I took some of the good parts from diggingforfire answer too.
Found anothe good answer that could be used as Best Practice here
Related
I am new to WCF and windows services.
I have wcf service that is called from a class library. I am using that library in Windows service(WS) and this WS subscribes to the services and executes call back methods. The problem here is when I use
wsDualHttpBinding, I get an exception at the highlighted line
subscribe () {
InstanceContext ctx = new InstanceContext(this);
fcsc = new FeatureCreationServiceClient(ctx, "MyEndPoint"); //error
fcsc.Subscribe();
error says
Could not find endpoint element with name 'xx' and contract 'xx' in the ServiceModel client configuration section.
Some of our friends in StackOverFlow suggested replacing wsDualHttpBinding with WShttpBinding. Now the problem is gone but there is new exception saying
Contract requires Duplex, but Binding 'WSHttpBinding' doesn't support it or isn't configured properly to support it.
Please help me. I know that some one might have already asked this question but my search for that was in vain. Thanks in Advance.
I'm looking for the correct way to have redundancy for a WCF service. I think I'm trying to solve a "infrastructure" issue in code. I'm not up to speed on load balancers but it seems like there should be something like routers to exactly this.
// Cycle through the list of service.
foreach (var uri in InfrastructureInformation.ServiceUris)
{
try
{
using (var client = WcfClientFactory.Create<ServiceClient>(uri))
{
// Do stuff here.
}
}
catch
{
// todo: Do not catch "exception" here. We have to find a better way of doing this.
// Try the next URI.
}
}
Seems like there should be a way to have one URI that I could hit that some "balancer" would hand off to an available service. If one service goes down for maintenance then the balancer would just not give any request to that service.
Now I know about WCF routing and I thought well that's the answer. Just put up a WCF router and have it hand out the connection but what happens if it falls over? Doesn't this give you a single point of failure? I'm looking for something more industrial.
WCF in .NET 4.0 has a routing capability that can be used in a failover scenario like you describe. This WCF sample shows how the built-in RoutingService class can be used for this purpose.
You could have a look at Microsoft Network Load Balancing (aka NLB). Microsoft also mention this in the context of WCF. There is an article on this here.
When a FaultException is returned from my WCF service, I need to Abort the channel instead of Closing it. Both my client and service work fine with this approach but after implementing IErrorHandler on the service and logging any exception, I can see that calling Abort on the client causes the service to log:
System.ServiceModel.CommunicationException: The socket connection was aborted...
I do not want to pollute my service logs with this information and only want to log service related errors. I know I can obviously stop logging any CommunicationExceptions but my service is also a WCF client for other services and CommunicationExceptions raised by these services should be logged.
How can I stop it doing this?
As nobody else has answered the question (Tomas's answer was not relevant), I asked a few experts in the field. Unfortunately, there is no nice way of stopping this and the best that they could come up with was to add logic in IErrorHandler to not log CommunicationExcepions with a message starting with 'The socket connection was aborted'. Not very elegant, but it does work.
The problem is that you get an exception that covers your underlying exception if you get an exception when calling dispose wich is possible. I wrote a wrapper to deal with scenarios like this, you can read about it on my blog: http://blog.tomasjansson.com/2010/12/disposible-wcf-client-wrapper/
The idea is that you have a wrapper around your channel that deals with the scenario if the dispose method throws an exception.
A small example of how you should use my wrapper:
public class ClientWrapperUsage : IYourInternalInterface
{
public IList<SomeEntity> GetEntitiesForUser(int userId)
{
using(var clientWrapper = new ServiceClientWrapper<ServiceType>())
{
var response = clientWrapper.Channel.GetEntitiesForUser();
var entities = response.YourListOfEntities.TranslateToInternal();
return entities;
}
}
}
Here I have assumed that it existing an extension method for a list that contains the entity that is returned by the service, then you use that method to translate it to internal entities. This is 100 % testable, at least I think :). Just moch the interface IYourInternalInterface everywhere you wan't to fake the service.
I'm putting together a WCF service using net.tcp and netTcpBinding to get duplex comms with my Silverlight client. I call into the service from the Silverlight app and the service calls out to another server, passing it a callback method in the WCF service class. The remote server calls back several times and each time it does, the WCF service uses the callbackchannel to send the data to the Silverlight client. It all works nicely most of the time.
If the user puts in a big request, I get a TimeoutException after a large number of callbacks have already worked. (Clearly, there's some work to do elsewhere to prevent this but I'd like to robustify the service, first.)
I was expecting to do some kind of 'if (client.ConnectionState == faulted)' check before trying to call back to the Silverlight client but I can't seem to find the object that holds the state of the connection. Is there one? Am I approaching this from the wrong side?
This is my first venture into a service net.tcp and duplex. I just moved house and my WCF bible is still in a box. Somewhere. :-) So, I can't do my usual background reading.
Any pointers would be gratefully received. Here's some bare code in case my description is too soupy:
private IActiveDirectoryClient client;
private AsyncSearchRunner runner;
public void Search(Request request)
{
this.client = OperationContext.Current.GetCallbackChannel<IActiveDirectoryClient>();
runner = new AsyncSearchRunner();
runner.Run(request.SearchRoot, request.SearchFilter, request.PageSize,
System.DirectoryServices.Protocols.SearchScope.Subtree, SendObjects);
}
private void SendObjects(List<DirectoryObject> items)
{
Response response = new Response();
response.DirectoryObjects = items.ToArray();
client.SendResponse(response);
}
Yes, there is a State property that is defined in the ClientBase<> class (all the proxy classes are derived from ClientBase<>).
There are some proxy wrappers out there that handle fault states of the connection and re-establish connections as needed. Google for "wcf proxy wrapper".
You can also home-brew something if you use some kind of ServiceLocator pattern.
I have a WPF appliction that uses WCF services to make calls to the server.
I use this property in my code to access the service
private static IProjectWcfService ProjectService
{
get
{
_projectServiceFactory = new ProjectWcfServiceFactory();
return _projectServiceFactory.Create();
}
}
The Create on the factory looks like this
public IProjectWcfService Create()
{
_serviceClient = new ProjectWcfServiceClient();
//ToDo: Need some way of saving username and password
_serviceClient.ClientCredentials.UserName.UserName = "MyUsername";
_serviceClient.ClientCredentials.UserName.Password = "MyPassword";
return _serviceClient;
}
To access the service methods I use somethingn like the following.
ProjectService.Save(dto);
Is this a good approach for what I am trying to do? I am getting an errorthat I can't track down that I think may be realted to having too many service client connections open (is this possible?) notice I never close the service client or reuse it.
What would the best practice for WCF service client's be for WPF calling?
Thanks in advance...
You're on the right track, I'd say ;-)
Basically, creating the WCF client proxy is a two-step process:
create the channel factory
from the channel factory, create the actual channel
Step #1 is quite "expensive" in terms of time and effort needed - so it's definitely a good idea to do that once and then cache the instance of ProjectWcfServiceFactory somewhere in your code.
Step #2 is actually pretty lightweight, and since a channel between a client and a service can fall into a "faulted state" when an exception happens on the server (and then needs to be re-created from scratch), caching the actual channel per se is less desirable.
So the commonly accepted best practice would be:
create the ChannelFactory<T> (in your case: ProjectWcfServiceFactory) once and cache it for as long as possible; do that heavy lifting only once
create the actual Channel (here: IProjectWcfService) as needed, before every call. That way, you don't have to worry about checking its state and recreating it as needed
UPDATE: "what about closing the channel?" asks Burt ;-) Good point!!
The acccepted best practice for this is to wrap your service call in a try....catch....finally block. The tricky part is: upon disposing of the channel, things can do wrong, too, so you could get an exception - that's why wrapping it in a using(....) block isn't sufficient.
So basically you have:
IProjectWcfService client = ChannelFactory.CreateChannel();
try
{
client.MakeYourCall();
}
catch(CommunicationException ce)
{
// do any exception handling of your own
}
finally
{
ICommunicationObject comObj = ((ICommunicationObject)client);
if(comObj.State == CommunicationState.Faulted)
{
comObj.Abort();
}
else
{
comObj.Close();
}
}
And of course, you could definitely nicely wrap this into a method or an extension method or something in order not to have to type this out every time you make a service call.
UPDATE:
The book I always recommend to get up and running in WCF quickly is Learning WCF by Michele Leroux Bustamante. She covers all the necessary topics, and in a very understandable and approachable way. This will teach you everything - basics, intermediate topics, security, transaction control and so forth - that you need to know to write high quality, useful WCF services.
Learning WCF http://ecx.images-amazon.com/images/I/41wYa%2BNiPML._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01_.jpg
The more advanced topics and more in-depth look at WCF will be covered by Programming WCF Services by Juval Lowy. He really dives into all technical details and topics and presents "the bible" for WCF programming.