views:

237

answers:

5

I have a WCF Service that I'm accessing in Silverlight. The Silverlight application requires authentication (authentication happens through a call to the service.)

I've noticed that when the authenticated session times out and the user does something application-side that would make a call to the service, the application just hangs waiting for the service to respond. My service is designed to output an exception in these cases, however nothing on the Silverlight side is assigned, and instead an exception is thrown:

CommunicationException was unhandled by user code

The remote server returned an error: NotFound.

In my service methods, I check to see if the user is still authenticated, and if so I continue with the operation. If not, I assign a value to an out parameter (of type Exception). On the Silverlight side, I check to see if this exception is null, and otherwise take the appropriate action. When I execute, the out parameter is given the proper exception, but then Silverlight throws the above exception (in Reference.cs) before it even gets to the point where I can handle it...

Has anyone else seen this? Any suggestions?

Edit: It seems that having any kind of Exception, including inheriting and containing them, causes the above exception. The simplest way I've found to get around this is just by passing the exception information inside my own custom Exception object (which again, cannot include the System.Exception object)

A: 

Thoughts and requests for more info:

You've checked your WCF service against a console app and everything works as expected?

You're able to make calls against your WCF service from your Silverlight app, and this behavior only occurs after the authenticated session times out?

Are you keeping your connection to the WCF open throughout the life of your Silverlight app? If so, I'd recommend only opening and closing it as needed. This way, you should only be calling it when the session is authenticated.

Terry Donaghe
Thanks for the response. In answer to your questions:1. I've checked the WCF service, yes. I've even stepped through the code line-by-line (more details in my follow-up comment...)2. Yes - I only have a problem when the user is no longer authenticated due to session time out (or if I create another window, browse the site where I'm automatically signed in, and I sign out, then return to the other window where the original signed-in state is maintained...)3. The service is only created and used as needed, and dumped otherwise.
AlishahNovin
The flow of events is this: 1. Silverlight makes the request, 2. WCF receives the request, and starts executing. 3. WCF detects the session is no longer active, and assigns the Exception, and returns a null value as well. 4. My silverlight app has code to check for exceptions, or otherwise use the value that is returned, but this code is never executed as the exception I mentioned earlier is thrown even before the Async "Completed" method is reached. I've verified this stepping through all the code, line by line. It all works fine when the user is authenticated.
AlishahNovin
I'm stumped. :) I'll be interested in knowing how the problem is eventually solved. I'll learn something! :)
Terry Donaghe
A: 

Enable WCF logging in your service and see what the output says. It is usually much more informative than just "NotFound". Here is some info on how to configure WCF logging:
http://msdn.microsoft.com/en-us/library/ms730064.aspx

Henrik Söderlund
A: 

Unless there's a special endpoint behavior defined for WCF services you are accessing (see http://msdn.microsoft.com/en-us/library/dd470096(VS.95).aspx) browser networking stack will convert ALL of the web service exceptions to 404 - and that's what you are observing.

So you have 2 choices:

  • if you can modify the behavior of WCF services you can add the endpoint as explained at the link above.
  • if you can't modify the behavior of WCF services you can switch to client networking stack by adding these lines to your App.xaml.cs file:

    HttpWebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp); HttpWebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);`

This will ensure that you get actual faults in Silverlight rather than 404.

Obviously switching to client networking stack has its own drawbacks (e.g. you will have to handle authentication, caching, cookies yourself)

PL
That caused all WCF calls to fail...
AlishahNovin
WCF needs to be configured to return HTTP 200 for faults.
DaveB
Well, by switching from browser networking stack to client one you lost some of the features provided by networking stack to you (e.g. authentication, caching, cookies) You have to decide if you want to handle faults in Silverlight (and thus deal with these other aspects yourself) or have these other features for free (and thus not being able to handle faults)
PL
A: 

This website seems to explain what I'm experiencing: Understanding WCF Services in Silverlight

Apparently Silverlight will get a 400 error for any exception, but will not have much clue what this exception is.

The author provides a solution, but I'm a little confused because the exceptions I've got aren't being thrown, merely assigned. I would think my implementation would work... can anyone provide any insight?

AlishahNovin
A: 

Take a look at my answer here:

http://stackoverflow.com/questions/2548076/random-not-found-error-with-silverlight-accessing-asp-net-web-services/

That is for an asmx service but the same applies to a WCF service. WCF faults are not passed through to the silverlight application. It just gets a 404 status code from the response.

Ritik Khatwani
This msdn article explains how to handle WCF faults in Silverlight. Hope it helps.http://msdn.microsoft.com/en-us/library/dd470096(VS.96).aspx
Ritik Khatwani