I’ve been getting a few notes on issues relating to people trying Silverlight beta 2 and WCF or other services. The most common issue I’m seeing reported is “my exception is showing a 404-not found error message, but the service is there and works!”
Okay, there could be several things happening here, but let’s tackle the “make sure it is plugged in” type situations. I don’t mean to make light of the error, because at first I, too, was banging my head against a wall. Sometimes it helps to have a second set of eyes or a deeper understanding of the issue…or both.
First, the situation. Most of the time you’ll see this exception when your Silverlight application is accessing a service not hosted on the same application domain. This is considered cross-domain access and requires the service host to enable an opt-in policy file so rich client platforms are allowed to access the service. In Silverlight we call that the clientaccesspolicy.xml file. You can learn all about cross-domain policy files by viewing this video on the Silverlight community site (a great resource). In beta 2, there was a subtle change to the policy file that is required. I wrote about that here as well (and note the code download for the video has the updated policy file).
Ok, so under what conditions might you get the “(404) Not found” error message when accessing services?
No policy file at all
Silverlight will first check for clientaccesspolicy.xml first and then fallback and see if a supported crossdomain.xml file exists. If neither exists at all, 404 baby. Also remember Silverlight is looking for this file in the root of the requesting domain. So if you have a file but it is in your app root…this could be the issue at all.
Incorrect, mail-formed, just plain wrong policy file
Silverlight will check for a clientaccesspolicy.xml file and if it finds one but it has an incorrect format or is mal-formed it will treat it as invalid and then look for crossdomain.xml…and if not found, boom: 404. This is what most are running into in starting to use beta 2 with your policy files. The missing http-request-headers attribute renders the file mal-formed.
Most sites have custom error messages for page not found. For example, when you visit google.com/timheuer you’ll get a less-than-helpful message, but custom nonetheless or as another example microsoft.com/timheuer you’ll get another custom response with a sitemap. Both of these are essentially custom error messages that are returning valid HTML, but not a valid policy file. In these instances, Silverlight sees the response, but sees it as invalid/mal-formed and treats it like it didn’t exist: 404.
These are the most common instances where a 404 would be generated and making you bang your head against the closest semi-hard surface. How can you figure out what is going on? Well first, make sure you do your best to ensure you meet all the requirements. But also use some development helper tools.
Web Development Helper
For me, in service/remote/AJAX development there is a single indispensable tool that I can’t live without. That is NikhilK’s Web Development Helper. This tool is a plugin to Internet Explorer (yes I know there are others similar in nature for Firefox, etc. – but I LOVE this implementation and IE is fine by me) that provides in the browser HTTP-traffic sniffing. No need for any funky port configuration or changing proxy server settings, etc. Just enable it and it works. I highly recommend you use this tool or something similar like it (Fiddler is another good one although requires some additional config steps usually when working with Visual Studio’s web development server).
Seriously, a tool like this will save you so much time in troubleshooting your service interactions with Silverlight, Flash, AJAX, whatever – it will help you immediately figure out where to start looking rather than grabbing your climbing gear and spelunking in unknown caverns.
So why a ‘404’ – what gives?
I’ve also heard people say “you need to make that exception be more descriptive, 404 is not accurate.” I’m on the fence on this one. As a .NET developer I can see where the concerns are coming from in having the most descriptive exception possible. But one must realize what is happening under the hood. The polciy file is being requested as a GET request, so basically an HttpWebRequest object is our object here. Because of this, we return HTTP-specific errors. There isn’t one for “Silverlight policy file found, but not correct” in the HTTP spec right now. So because of this, we use a RESTful approach in providing a standard HTTP response. In our case “404-not found” seems to be a valid response – indicating “The request for a valid policy file resulted in a valid policy file not being found.” We make no distinction between partially valid or finding a specific typo, etc. – we simply indicate that a valid policy wasn’t found. One could argue 406,409 or 417 might be other responses, but I’m not sure that would make anyone feel any better – we’re still going to use an HTTP response code.
Hope this helps!