Silverlight Communication Exception

Cross Domain Access

I hope this article can save someone some of the pain I have just experienced trying to get my Silverlight 2 app talking to my ‘cross domain’ WCF service (that is hosted in a console app).

I’ll leave discussing why I didn’t just host my SL app with my WCF service and avoid all of hassles until the end of the article. I’m also not going to discuss how to set this up, I’ve provided links to articles that I found useful for this.

The Error

An error occurred while trying to make a request to URI ‘http://localhost:4522/MyService’. 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. Please see the inner exception for more details.

Existing Blog Articles

I found many useful articles, many of them with at least one little extra thing to try, these are the most useful:-

  1. Silverlight forum discussion on the cross domain policy
  2. Great step by step article to showing how to setup an SL project to consume a WCF service hosted in a Console (I thought this for sure would have all my answers)
  3. MSDN has what looks like the content needed for both the crossdomain.xml and clientaccesspolicy.xml (but it’s not quite right).
  4. Interesting discussion on crossdomain.xml and clientaccesspolicy.xml.
  5. StackOverflow thread.
  6. Cross-domain Policy File Specification. This is what eventually led to me trying something that finally it all working!

All of this (and a number of others I looked at) helped, they really are great articles and I could see comments at the bottom saying things like “thanks got it working now!”. Problem was I had very closely checked and rechecked what I had done vs what was in these blogs and still I kept getting the error!

The Solution

After many hours of trying many different things I came across theΒ  and tried an extra little line and voila…working service! That’s a great feeling isn’t it…when you’ve been trying to find a solution to a problem for hours…and hours…you know there must be an answer but everything you try should work but dammit it doesn’t…and then…suddenly…you tick some obscure buried box somewhere and the universe is back to the way it should be…

anyway I digress…this is what MSDN says you should put in your crossdomain.xml file

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
  <allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>

This is what actually works!

<?xml version=”1.0″?>
<!DOCTYPE cross-domain-policy SYSTEM “http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd”&gt;
<cross-domain-policy>
<allow-access-from domain=”*” />
<allow-http-request-headers-from domain=”*” headers=”SOAPAction” />
</cross-domain-policy>

I’ve highlight the important line. You’ll notice that the MSDN sample has headers=”*”,Β  this simply does not work. In fact if I add the extra line that makes it work and headers=”*” is still in the first line, then everything still fails. So delete headers=”*” and add the new line.

Another thing to note, I noticed amongst the articles posted on this subject that if you have a clientaccesspolicy.xml file then you don’t need a crossdomain.xml file. Maybe this is true with their setup but I have found that you must have a crossdomain.xml file, in fact after a bit more trial and error I have come to the conclusion that the clientaccesspolicy.xml just does NOT WORK! At least for me. If my SL app finds it then I get the error…no matter what I put in there. Only when my service does NOT return it but DOES return a crossdomain.xml file with the correct format above does it work.

Maybe this was all a peculiarity of hosting the WCF service inside a console app? Not sure. Don’t care at this point, the thing finally works…yay!

Do I Need a File

You can choose to create the required xml in code or you can have the physical file, your choice. Most of the examples just create it in code. It’s not the existence of the file that matters, just the contents and the web GET request must be able to retrieve the content.

By the way, all examples I have seen (including mine) leave your service completely unsecured. I strongly recommend learning how to set these policy files up properly so that your service isn’t nakedly exposed to the outside world.

What Didn’t Help

In case you have some other problem, these are the things I can say didn’t make a difference. Once I got it working I tried with and without these things and my cross domain connection still worked.

1. Does setting the ContentType help?

WebOperationContext.Current.OutgoingResponse.ContentType = “application/xml”;

Nope doesn’t matter.

2. Some blog samples show a return type of ‘Message’ and others a return type of ‘Stream’ for the method that this attribute goes on:-

[WebGet(UriTemplate = “ClientAccessPolicy.xml”, BodyStyle = WebMessageBodyStyle.Bare)]

Does the return type matter? Nope doesn’t matter (well I only tried these two types, I guess it should be one of these)

3. I read you should decorate your services with this attribute…is it needed?

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

Nope, didn’t help. (note that it didn’t help with THIS problem, I’m sure there is some good reason for why you would use it)

So Why Bother With Cross Domain?

  1. In an enterprise environment it is very likely that you will need to call a number of different services. Sure you could have one WCF service that is just for your SL app that then goes off and talks to all of the disparate services for the SL app but that just doesn’t seem right to me. (just an opinion and hey in some cases it probably is appropriate…)
  2. Isn’t it all about separation of concerns? When I’m working on server side code I only want server side projects in my solution and vice versa for client solutions. This keeps the number of projects in my solution down…thereby keeping Visual Studio (and resharper) at least a little bit responsive.
  3. When the server is working I just want it running. I don’t want to have to compile and start the server every time I want to debug something in my client code.

Hmmm, I’m sure there’s other reasons but I can’t think now given it’s 3am 😦

Anyway I hope this helps someone save some time πŸ™‚

  1. Thanks! Was pulling my hair out trying to get the stuff off of MSDN and associated forums/blogs to work. Your’s worked for me. thanks for sharing.

  2. Rock on dude! Thanks Mark…after 100 pages of reading, this one did the trick.
    I was using IIS (not port/cassinni) for my project. And I put the file here:
    C:\Inetpub\wwwroot\crossdomain.xml

      • Sunil
      • November 28th, 2011

      Thanks for your wonderful post! I might have gone thru 1000 pages and messed-up with IIS to resolve the issue. This one worked!

    • Kevin
    • August 11th, 2009

    Thanks Mark. Was annoying me big time!!

    I was using IIS for my project. And I put the file here:
    C:\Inetpub\wwwroot\crossdomain.xml

    Thanks again.

    • Jan
    • August 31st, 2009

    Hi, I am having the same problem, but I think I must be missing something else. I have a self-hosted WCF server, and I am getting the same exception. I added the methods that generate the two XML files, but these methods do not get called. Any idea?

      • wallism
      • September 1st, 2009

      Only thing I can suggest is to make sure you have a service setup to handle the request.

      1. Create the interface
      ///
      /// Allows the service to be available cross domain,
      /// specifically for Silverlight.
      ///
      [ServiceContract]
      public interface ICrossDomainService
      {
      // uncomment this if you want to return a clientaccesspolicy.xml
      // if you do this then I think crossdomain won't work!
      // [OperationContract]
      // [WebGet(UriTemplate = "ClientAccessPolicy.xml")]
      // Message ProvideClientAccessPolicyFile();

      ///
      /// Retrieve the text from the CrossDomain.xml file (or from the method)
      /// as a message
      ///
      [OperationContract]
      [WebGet(UriTemplate = "CrossDomain.xml")]
      Message ProvideCrossDomainFile();
      }

      2. Implement it
      public class CrossDomainService : ICrossDomainService
      {

      public Message ProvideCrossDomainFile()
      { ... your code that generates the xml

      3. Add the service in your config file and make sure it gets started with your other service(s). (I’ve ‘un-xml’ed below so would work in the comment)
      *service name="PeerConnect.Wcf.ConsoleHost.Security.CrossDomainService"
      behaviorConfiguration="PeerConnectDebug"*
      *endpoint address=""
      binding="webHttpBinding"
      contract="PeerConnect.Wcf.ConsoleHost.Security.ICrossDomainService"
      behaviorConfiguration="CrossDomainEndpointBehavior"*
      */endpoint*

      Put a breakpoint on the ProvideCrossDomainFile method and if the service is started properly it should be hit when your your SL app makes a request.

      Good luck!

        • ben
        • December 17th, 2009

        This looks promising! but how do I get the webget method? System.servicemodel.web does not seem to be in the list of available references for my wcf project. How do I make this happen? Is it something I need to download?

        • wallism
        • December 17th, 2009

        Are you looking server side?

        WebGetAttribute is in System.ServiceModel.Web but on the server side.

        The way I’m using it looks like this

        ///
        /// Allows the service to be available cross domain, specifically for Silverlight.
        ///
        [ServiceContract]
        public interface ICrossDomainService
        {
        ///
        /// Retrieve the text from the CrossDomain.xml file (or from the method) as a message
        ///
        [OperationContract]
        [WebGet(UriTemplate = "CrossDomain.xml")]
        Message ProvideCrossDomainFile();

  3. Stunning, I did not heard about that until now. Thx!

  4. WOOOOOOOOOOOO !!

    LOL ! The outburst in emotion represents days of configuration struggle. I have a proof of concept demo tomorrow, your solution is priceless, gives me just enough time to get it done. Thanks a million.

    Michael

    • Pete
    • January 19th, 2010

    All i can say after two days of bashing my head in and wondering if I am stupid or MS is stupid, it is nice to know again that it was them. lol. Another thing that helps ALOT was making sure to do a check on the ClientConfig files to make sure that the bindings are set as basicHttpBinding for WCF. Also check the contract to make sure that the objects are assigned correctly, lastly, look at the port numbers. Again, your solution for the crossdomain.xml is the ONLY solution I have found to work.

      • wallism
      • January 19th, 2010

      Thanks for the comment Pete, glad the solution got things working for you πŸ™‚

    • Slava
    • July 6th, 2010

    You saved me. I’ve spent one day in order to solve this problem and worked with MSDN xml file. Stupid mistake on their site, but I had to pay for it. Thank you!!!

    • sujatha
    • August 13th, 2010

    Sujatha

    Hi this is working fine for me after a long struggle with your example I fixed the issue.
    Thanks!

    • Robin
    • September 27th, 2010

    Thank you very much for sharing this solution!

    I’m new in the WCF and Silverlight scene.

    And just in that 2 minutes your help brought my first WCF plus Silverlight apllication to life πŸ˜‰

    • Andrija
    • March 30th, 2011

    I can say same thing as previous users! This thread saved my day. I tried all stuff and only adding crossdomain.xml helped. I just returned created XML with XDocument from my REST service, and vola Silvelight application start communicating

    • Hendra Pratama
    • September 29th, 2011

    U ARE DAMN GOOD.
    It did help
    Thanks… thanks…thanks…

    • wallism
    • July 27th, 2009

    yeah it bugs me too, it SHOULD work and I’m sure I’m missing something, there must be some magical box somewhere that I need to tick…

    If you ever get any more insight into this I’d be very keen to hear it πŸ™‚

    btw – thanks everyone who left a message, nice to know posting about my pain has helped someone πŸ˜‰

  1. July 25th, 2009
  2. December 21st, 2010
  3. January 7th, 2011

Leave a reply to Sunil Cancel reply