Do CommunicationExceptions need to be handled on Server Side in WCF? - c#

Do CommunicationExceptions and/or TimeoutExceptions need to be handled in the Service Implementation? (in addition to the client?). What happens when a client times out ? Does the service continue processing the message, or does an exception get thrown?
Thanks
-Vic
For example do, I need to do the following ??
public MyServiceImpl:IMyService
{
void DoSomething()
{
try{
//Do something
}
catch (Communication exception){}
catch (Timeout exception){}
}
}
}

Since you're not in a callback scenario, your service method won't even be called if there's a timeout (since it will be catched by the various dispatchers that get the message before your method does). So no need to catch these exceptions here.
If you're using a Stream as one of the parameters of your operation, things are a little different though, since you're likely to run into an exception while reading the stream if your client throws a hissy fit. But in that case you'd have to guard for exceptions anyway.

As per usual: it depends :-)
If you have per-call instancing, or one-way messages, then even if a bad thing (an exception) happens on the server, they'll be propagated to the client (or in one-way scenarios: just dropped), and you don't have to worry about them all that much.
HOWEVER: if you have a session scenario, where either your transport protocol (TCP/IP in the case of netTtcp binding) uses a transport session, or where your e.g. wsHttpBinding establishes an application session with the server, then you need to make absolutely sure on the server to catch all exceptions and handle them and return them only as SOAP faults.
If you don't, then the channel (the communication pipe between your client's proxy instance and the server instance) will be "faulted", e.g. unusable and the client proxy instance will need to be recreated.
Also, keep in mind that .NET exceptions are just that - a .NET specific thing. If your service will need to be interoperable and be called from e.g. Java, Ruby, PHP or other clients, you absolutely MUST catch all .NET exceptions on the server side and turn them into SOAP faults (which are the interoperable equivalent). You can do this by implementing the IErrorHandler interface on your server side.
Marc

Related

wcf oneway non blocking operation

I need such scenario: client sends message to server, not waiting for response, and don't care, if message was send properly.
using(host.RemoteService client = new host.RemoteService())
{
client.Open();
cliend.SendMessage("msg");
}
in scenario when firewall is on, or there is no connection to the internet, client dies at "SendMessage". I mean program stops to respond. I wish program don't care about the result. I mean if there is no connection, i wish program to go further, omitting "SendMessage" or sth like that.
What should I do, is there any solution for non blocking method?
Try something like this in your service contract:
[OperationContract(IsOneWay=true)]
void Send(string message);
See the following link:
One Way Operation in WCF
Edit: OP was already using my suggested solution.
Suggested approaches to solve the issue - taken from MSDN (One-Way Services):
Clients Blocking with One-Way Operations
It is important to realize that while some one-way applications return
as soon as the outbound data is written to the network connection, in
several scenarios the implementation of a binding or of a service can
cause a WCF client to block using one-way operations. In WCF client
applications, the WCF client object does not return until the outbound
data has been written to the network connection. This is true for
all message exchange patterns, including one-way operations; this
means that any problem writing the data to the transport prevents the
client from returning. Depending upon the problem, the result could
be an exception or a delay in sending messages to the service.
You can mitigate some of this problem by inserting a buffer between
the client object and the client transport's send operation. For
example, using asynchronous calls or using an in-memory message
queue can enable the client object to return quickly. Both
approaches may increase functionality, but the size of the thread pool
and the message queue still enforce limits.
It is recommended, instead, that you examine the various controls on
the service as well as on the client, and then test your application
scenarios to determine the best configuration on either side. For
example, if the use of sessions is blocking the processing of messages
on your service, you can set the
System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode
property to PerCall so that each message can be processed by a
different service instance, and set the ConcurrencyMode to
Multiple in order to allow more than one thread to dispatch messages
at a time. Another approach is to increase the read quotas of the
service and client bindings.
Modify your attribute
[OperationContract(IsOneWay=true)]

Disposing WCF with long running [OperationContract(IsOneWay = true)]

I've following service, defined as OneWay, because it's long running (a few minutes) and I can't wait when it finishes (it's used in ASP.NET application).
The problem is that if I call client.Dispose() after the service call, it blocks and after 60s timeout expires with exception.
How should I dispose the client in such scenario? Increasing the timeout of the service isn't solution, because I can't wait so long time with the HTTP request of the web page, where it's used.
[ServiceContract]
public interface IMyService
{
[OperationContract(IsOneWay = true)]
void BeginRun();
}
var client = new MyServiceClient();
client.BeginRun();
client.Close(); //This leads to time-out, how and when to call it?
Thanks for tips.
I would switch your binding to netMsmqBinding. Then from your client your one-way calls will be instantaneous.
Long duration sends over http are problematic at best and complex to manage. Sticking a queue in between will greatly simplify this operation.
From your signiture, it seems like you don't need any sort of response. In that case, on the service, when you recieve the BeginRun() call, execute the work on a non-WCF thread. This will free the channel & should allow you to immediately dispose the client.
Even though you've marked the OperationContract as IsOneWay, that doesn't mean WCF immediately releases the channel. A WCF service will not actually return from a one-way call until all of the data has been read from the wire. Depending on your service configuration, this could involve waiting for previous calls to complete (particularly w/ Single concurrency mode sessionful service configurations).
So, for several reasons it's often a good idea to actually execute service work on a separate thread from the WCF thread, which should improve throughput. Take a look at this article on MSDN for additional details.
You can try the IChannel approach. Or maybe try this, not sure this will work : http://msdn.microsoft.com/en-us/library/ms731177.aspx
You need to add try catch block inside your code and if there is an timeout exception it should abort the client.
try
{
work(client);
client.Close();
}
catch (Exception e)
{
client.Abort();
throw;
}

WCF client's Open() method no longer throw exceptions after security is disabled. What to do?

I have a WCF service-client pair. We have been relying on calling Open() on the client's factory method to make sure that the service is available before we make any call. Something like:
MyClient GetClient()
{
MyClient client = new MyClient();
try
{
client.Open();
return client;
}
catch(Exception)
{
//perform an (important) error-handling here
}
}
In this way, the caller codes will just do something like:
client = factory.GetClient();
client.CallMethodInTheService();
and they don't need to worry about error handling.
This works when we set security mode to Windows and clientCredentialType to Windows in the wshttpbinding. client.Open() will throw an exception when service is unavailable, so the error handling code will get executed. However, now we are deploying in an environment where we cannot use Windows credential based security, so we set security mode to none. However, this cause client.Open() no longer throws an exception when the service is unavailable, and we have some problem because we rely on this code in the catch block of the factory.
What is the reason that Open() throws an exception when we use message security but not when we disable the security?
How can we perform similar availability checking if security is set to none? I don't think it's a good solution to put a try catch with error handling on each individual call. Is there another way for the factory method to check the availability of the service before returning the client object?
The exception will not be thrown with any security but only in cases where a session is involved. e.g. establishSecurityContext=true or negotiateServiceCredentials=true (the defautls). In those cases before the first call to the server the client will send some infra messages to it in order to decide on a cryptogtaphic key to use. When you call open() you explicitly ask to make this negotiation now (otherwise it will happen on the first call). If you turn on Wcf logging (or Fiddler) you will see this.
When the service is not avialable the negotiation will fail so you get an exception.
Without security there is no session so no exception.
I suggest you add a IsAlive operation to the service.

Best practice to handle WCF service errors?

I am coding some kind of a WCF service. most exceptions are caught in the BL implementation and handled there. Each of my API's return type is a class (named - "result") containing error code, error message and success boolean.
When exceptions are handled, this class is updated accordingly and in the end is sent back to the client.
Some of the exceptions are off-course, unhandled. Currently, I am wrapping each of my BL calls from the service layer with a generic try-catch so I can catch every unhandled exception and create a generic "result" class with a generic failure message, error code and success=false.
Is it a good way to handle exceptions or should I let unhandled exception to be thrown by the service to the client?
You can assume that the client can't use the data from the exception so it won't benefit from the extra information contained in the exception.
Check out Exception Shielding.
This is a process where exceptions raised by the service, are mapped to fault contracts according to rules you specify in a configuration file. This saves a lot of donkey work with try/catch blocks.
Here is one post to help you out:
In general though - faults will fall into 3 categories:
1) Client error - the client has tried to do something not permissable, so it needs to know about it. E.g. Failed to set a mandatory field. - Return specific message explaining fault.
2) Business error that doesn't affect the client. An error that is considered normal operation, e.g. Payment Authorization check failure. Either hide from client completely, or return some message: "Error performing request: Please try again later..."
3) System error - Unexpected - not normal operation: Replace with generic message: "System Error: Call Support"
In all cases though, the key thing is you remove the stack trace, especially if it's a public facing service.
With shielding you would have 3 Fault Contracts covering the above scenarios, and set the text appropriately in the Shielding configuration.
Be advised, you generally want shielding turned off during development as it makes it a right pain to debug the system!
I differ with the others. I think that in the same way HTTP methods GET, POST, PUT, DELETE thereby support CRUD operations, HTTP response codes 200, 500, etc., support success/fail and this is, in my opinion, appropriate to make use of. A 500 result still has an HTTP response body, and such a body is fully readable (so long as IIS isn't spitting out HTML; you have control over this). Meanwhile, the XML protocol implementations as with Microsoft SOAP from WCF already wrap exceptions with a faulting protocol.
If you're going to throw exceptions, throw them. Just document them while doing so, so that the consumers can plan accordingly.
I think both approaches are viable.
I personally prefer not throwing exceptions over WCF, so that the client can easily distinguish between error in server-side processing and connectivity/protocol issue: in the first case the response will indicate the failure, and in the second case exception will be thrown.
Personally I wouldn't expose the unhandled exceptions and propagate them to the client. I would define those exceptions the client might be interested in and only propagate those. Exceptions not directly related to what the clients want to do (ArgumentException could set reason to "CustomerId cannot be more than 20 chars" etc.) I'd deal with in the service and only indicate that some sort of internal server error has occurred on the service side which broke the execution and meant that the operation the client tried to run failed to complete. This I would do because the client can't really take any action based on internal server errors. They can fix their inparams in the case of an ArgumentException being thrown by validating the parameters again and retry the operation.
Not sure if this is really what you're asking, but hope it gives you some ideas at least.
If you let unhandled exceptions out of your WCF service, this may have undesirable effects such as communication channel being in faulted state where in a sessionful scenario, client can no longer use the same client proxy instance but is forced to create a new one and start a new session. In general, I think it is good to have control over the errors that surface out of your WCF service and provide clients helpful information. Take a look at IErrorHandler.This interface gives you control over the SOAP fault generated, unhandled exceptions, and allows you to do extra tasks like logging, and lets you decide whether you want to keep the session or not in case of a sessionful binding. You add your custom error handler via WCF extensibility such as service, endpoint, contract, operation behaviors.
Note that IErrorHandler is called before sending a response message. So there is still a chance of an unhandled exception occurring down in the channel stack during serialization, encoding, etc.

Is it Ok to throw exceptions back to a client from my service?

I am writing a Java based service with WSDL for a .Net client to consume, and I thought that when I receive an invalid value from the client that I would throw an exception that my client could then catch and display in a message box or something to the user (the client is a desktop app).
I was wondering if it would be ok to use this approach or if there's a better way of doing it.
I would say "no". Error messages, etc., but I wouldn't serialize an exception. You have no idea who the client is or what language they're written in.
The service should handle the exception: catch it, log it, and create a sensible error message(s) and status codes. This is not the place for exceptions, in my opinion.
And when I say "sensible error messages", I don't mean anything resembling a stack trace. These are likely to be business clients, who should not be reading such things. A business-meaningful message is the ticket here, not a stack trace.
.NET in general deals in FaultExceptions (wrapped SOAP faults) in WCF. I would assume that if you throw a proper SOAP Fault, that WCF would wrap this up into a FaultException by the time the client consumes the response, so they can have a try catch FaultException statement. This would still allow other non .NET clients to consume the service without breaking standards..
Just an idea anyway...
What you should probably do is use SOAP Faults, since these should be supported for any clients. Be sure to set the extra descriptive fields too.
Conceptually this is fine, but I don't think you can literally throw a Java Exception over HTTP back to a .NET client.
You can use HTTP 500 to signal a server error; you should also be able to attach a meaningful message to the response that will help the .NET developers figure out how to use your service better. This may or may not include a serialized Java stack trace.
The first thing to tackle is preventing against exceptions being thrown by doing validation on data before it gets manipulated. IE
string func(string cat)
if(cat == null || cat.length == 0){
//set errorLabelText to "bad data"
return;
}
//else code
That being said only throw Exceptions in Exceptional cases.

Categories

Resources