Silverlight and WCF: Handle 'WCF down' exception / WCF connection check - wcf

Inside my Silverlight app, I'm calling a web service asynchronously, using the client generated for me by Visual Studio (Add Service Reference...).
My code looks like this:
ServiceClient serviceClient = new ServiceClient();
serviceClient.GetServerTimeCompleted += new EventHandler<GetServerTimeCompletedEventArgs>(serviceClient_GetServerTimeCompleted);
serviceClient.GetServerTimeAsync();
void serviceClient_GetServerTimeCompleted(object sender, GetServerTimeCompletedEventArgs e)
{
// do nothing atm
}
Everything works fine as long as the service is up and running, but when the service isn't running, i get:
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
"An exception occurred during the
operation, making the result invalid.
Check InnerException for exception
details."
InnerException
"An error occurred while trying to
make a request to URI
'http://'. This could be
due to attempting to access a service
in a cross-domain way without a proper
cross-domain policy in place, or a
policy that is unsuitable for SOAP
services. You may need to contact the
owner of the service to publish a
cross-domain policy file and to ensure
it allows SOAP-related HTTP headers to
be sent. This error may also be caused
by using internal types in the web
service proxy without using the
InternalsVisibleToAttribute attribute.
Please see the inner exception for
more details."
It makes sense that I get an exception under these circumstances, but what I can't figure out is how to catch the exception in my client code. Is there a standard way to do this? If I understand how this is working, when my code calls the generated code, it spawns another thread that actually calls the web service and waits for the response. The exception is in that thread and in the generated code. Neither my calling code (see above) or my callback method have the opportunity to see the exception.
Thanks
Christian

There are a number of reasons not to use the "Add Service Reference" functionality in Visual Studio. Here's a good (and long) article on the issues, and how to use WCF creating your clients. I'm working through these issues myself, right now.
Among the concerns about "Add Service Reference" include code bloat in the downloadable client .XAP file, difficulty in maintaining generated code, difficulty in staging or shipping code when the server addresses and ports are hard-coded in the client config file (also embedded in the .XAP), and lots more. Building your own clients will also give you better capability to manage exceptions in client code.
There are some tradeoffs; you'll need to make your data contract classes portable to the Silverlight environment. (You can't just add a reference to a server-side .NET assembly; it doesn't work.) There same site linked above has a good article on re-using assemblies in Silverlight, but probably the easiest way to deal with this is to add links to your server-side classes from your Silverlight project. (In the Silverlight project, right-click and Add -> Add existing item... and find the item you want to include, but instead of clicking on the Add button, click the down-arrow beside it and click on "Add as Link".) Watch out for other references and using statements that refer to server-side classes; you may need to do conditional compiles so that your data contract classes compile cleanly in the client-side project.
Overall, it really looks like a cleaner way to go, especially for large projects that may use lots of service contracts and data contracts, or where you need to ship your Silverlight projects as part of a commercial application that runs on other people's servers. It should also be a lot cleaner for testability, especially for integration and staging testing.

I have encountered this problem before - you need to add exception handling code around your ServiceClient setup code. I typically check for the following CommunicationException, TimeoutException, and EndpointNotFoundException and provide the user with an appropriate dialog telling them something is broken:
ServiceClient serviceClient;
try
{
serviceClient = new ServiceClient();
serviceClient.GetServerTimeCompleted += new EventHandler<GetServerTimeCompletedEventArgs>(serviceClient_GetServerTimeCompleted);
serviceClient.GetServerTimeAsync();
}
catch (EndpointNotFoundException ex)
{
// log exception
// show error dialog
}
Note: this will not handle errors encountered during the asnchronous method callback - it will need it's own (similar) exception handling.

Actually you have to put crossdomainaccesspolicy.xml in IIS default website root folder.
you copy the given below xml content and save in the name of ClinetAccespolicy.xml and then put on the IIS default website root folder.

Related

How to Implement the fault Contract/Exception handling in WCF and Silverlight?

I have already developed my application, which has more than a 1000 functions. Now I need to implement fault contracts or exception handling in Silverlight without changing these functions.
Is there any common method that I can implement in one place in the WCF service layer and in one place in the Silverlight Application?
I want to implement this because when any exception occurs in the WCF layer, it will not send the real exception message to silverlight.
Silverlight only gets a message like this:
"Remote server not found..."
Real problem is i have already developed the system and now i need to implement the falultcontracts without changing too much or each function in Service layer.. so is there any method to create the falutcontract wrapper and place it over the WCF service Layer?
It's not 100% clear to me from the question what's going on in your case, but I can mention:
If you get an exception in Silverlight that the "Remote server not found..." then you won't get any exception details no matter what you do in the service (how can the service respond with those details, if the Silverlight app can not find the service?).
If you want to see exception details from the service in your app for debugging purposes, you can apply it to the entire service through the IncludeExceptionDetailInFaults property in the ServiceBehavior. This is considered a security risk (disclosing internal exception details) so it's not recommended for production.
As far as I know FaultContracts have to be set on the operations themselves, and you have to be explicit when you throw them.
PS. Your real problem may be that you have over a 1000 functions in your service, that doesn't seem healthy. On the other hand, if they are generated functions it may turn out to be a mixed blessing as you may be able to generate some fault code as well?

What is the easiest way to log exceptions from a WCF service to a the Windows Event Log?

I want to log all exceptions (including serialization exception stack traces) in a WCF server to the Windows Event Log (log4net logging would also be acceptable).
What is the easiest way to do this?
Specifically all errors in serialization, in the service itself, etc. Right now I'm using tracing to get serialization errors during development. Tracing was the only way I could find out what object was actually have a problem with serialization. See Quickly finding WCF Serialization/Deserialization Issues for an example of getting the serialization stack trace.
I can handle errors in the service code itself. However, errors in the WCF machinery don't propagate to my service code (like serialization errors).
I don't need to send the errors to the client.
I just want to get the errors into one location (like the Event Log).
Right now (from my research) it appears that the IErrorHandler Interface with some custom code might be the best way to proceed. Will using the IErrorHandling interace catch the serialization exceptions?
Edit:
This may be the answer I'm looking for:
How do I create a global exception handler for a WCF Services?
I'd just like a confirmation that this will catch serialization errors and more importantly the details of those errors, also.
More Info:
How do I create a global exception handler for a WCF Services?
Yes, IErrorHandler will also catch serialization exceptions. You will get all information stored in the exception. Whether or not this enough detail for you, I can't say.
Note that there may be client-side errors (serialization and others) which will never make it to the server. You will not see those with the IErrorHandler.

Turn off WCF SOAP Service for Maintenance and provide friendly message

I'm hosting some SOAP services with WCF. How can I turn off these services via config for the purposes of maintenance, etc., and provide a friendly message to the service consumer with something like "The service you've requested is down for maintenance."?
You would have to have a second service, that offered the same interface, same methods etc., that would all return that friendly message instead of a real result.
That might get a bit trickier when those service methods don't just return a string but a complex data object - where do you put that "friendly" message??
In reality I think this cannot really be done - since your services typically aren't "seen" by actual people, you cannot just put up an app_offline.htm file or anything like that.
Try to have as little downtime as possible, by e.g. setting up your new version of the service on a new port and testing it there, until you're confident enough to switch over.
With WCF, it's mostly an exercise of updating / copying around the appropriate config, so your service should never really be unavailable for any extended period of time (hopefully!).
If you really must, what you could do, is just have a replacement service that will always throw a FaultContract<ServiceDownForMaintenance> - but then all the clients calling your service would have to know about this and they would have to handle this case and present an error or information message. Your service can't really provide that...
How about this: create a custom ServiceBehavior to intercept my incoming requests to the service. Then, have the custom behavior check a user-defined flag in my config file, something like <add key="IsMyServiceUp" value="true" /> and if that value returns as false then throw a ServiceException with my friendly message and HTTP code of 503 - Service Unavailable.
Does that sound reasonable? Then all I have to do is change the flag in my config file to specify where the service is up or down.
Okay, so I've created a new Custom Behavior that implements IOperationBehavior. In the Validate method, I've got
public void Validate(OperationDescription operationDescription)
{
bool isServiceUp = Boolean.Parse(ConfigurationManager.AppSettings["IsOrderServiceUp"].ToString());
if (!isServiceUp)
{
throw new ServiceException(ServiceErrorCode.Generic_Server_Exception,
ServiceErrors.Generic_Server_Exception,
SoapFaultCode.Server);
}
}
The other implemented methods ApplyClientBehavior, ApplyDispatchBehavior and AddBindingParameters are all empty.
I have decorated one of my service operations with [ServiceStatusValidation] which is the class name of my custom behavior.
When I start the service and navigate to the operation with this decoration, I do NOT get the exception I've thrown. SOAP UI shows nothing as returned in the response pane, and my consuming REST facade gives a generic 400 error with The exception message is 'The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.'.
Any ideas? Should I be doing this logic in one of the other methods that I didn't implement instead of the Validate method?

how to create and manage wcf service clients?

At first I treated them as any dependency passing them in the ctor to the class consuming the service:
var serviceConsumer = new ServiceConsumer(new MailingServiceClient())
The problem was that once an exception was thrown from the service it entered a faulted state and would not reply to any requests, so re-initialization was due.
Further more, I became familiar with the fact that wcf services may not be disposed properly on several occasions, because the dispose method of the generated proxy is broken (calls close without checking the fault state) and encountered a couple of ways to overcome that:
wrapping every call to every service.
override the default IDisposable behavior of the scvutil.exe-generated class
Since I wouldn't like the consumer code to create the service client himself for testing reasons, my questions are:
how can I maintain a working un-faulted service?
how can I still use dependency injection for testability?
Found a nice solution.
a proxy generator that replaces the VS one, and generates a wrapper around the default proxy that deals with proxy faults, timeouts, and correct disposal.
http://wcfproxygenerator.codeplex.com/
seems to be working fine for me.

WCF using Enterprise Library Validation Application Block - how to get hold of invalid messages?

I've got some WCF services (hosted in IIS 6) which use the Enterprise Library (4.0) Validation Application Block. If a client submits a message which fails validation (i.e. gets thrown back in a ValidationFault exception), I'd quite like to be able to log the message XML somewhere (using code, no IIS logs). All the validation happens before the service implementation code kicks in.
I'm sure it's possible to set up some class to get run before the service implementation (presumably this is how the Validation Application Block works), but I can't remember how, or work out exactly what to search for.
Is it possible to create a class and associated configuration that will give me access to either the whole SOAP request message, or at least the message body?
Take a look at using the Policy Injection Application Block...
I'm currently developing an application in which I intercept (using PIAB) all requests incoming to the server and based on the type of request I apply different validation behavior using the VAB.
Here's an article about integrating PIAB with WCF:
http://msdn.microsoft.com/en-us/magazine/cc136759.aspx
You can create different inteception mechanisms such as attributes applied to exposed operations.
You could log the whole WCF Message:
http://msdn.microsoft.com/en-us/library/ms730064.aspx
Or you could combine it with Enterprise Library Logging Application Block.
I found a blog post which seems to do what I want - you create a class that implements IDispatchMessageInspector. In the AfterReceiveRequest method, you have access to the whole incoming message, so can log away. This occurs after authentication, so you also have access to the user name - handy for logging. You can create supporting classes that let you assign this behaviour to services via attributes and/or configuration.
IDispatchMessageInspector also gives you a BeforeSendReply method, so you could log (or alter) your response message.
Now when customers attempt to literally hand-craft SOAP request messages (not even using some kind of DOM object) to our services, we have easy-to-access proof that they are sending rubbish!