Friday, October 28, 2011

Cross domain policy for silverlight to access a WCF Service

Today, I'm posting about an issue which I faced when making a WCF Service to be accessible across different domains. And this was for a silver-light chat application. The chat application didn't work for me, and it threw me the below error when I debugged.
"An error occurred while trying to make a request to URI http://SampleSite/Chat Service.svc. 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."
After going through the MSDN, I was able to solve the issue.

"To enable a Silverlight control to access a service in another domain, the service must explicitly opt-in to allow cross-domain access. By opting-in, a service states that the operations it exposes can safely be invoked by a Silverlight control, without potentially damaging consequences to the data that the service stores.

Silverlight 4 supports two different mechanisms for services to opt-in to cross-domain access:

  • Place a clientaccesspolicy.xml file at the root of the domain where the service is hosted to configure the service to allow cross-domain access.

  • Place a valid crossdomain.xml file at the root of the domain where the service is hosted. The file must mark the entire domain public. Silverlight supports a subset of the crossdomain.xml schema. "
                                                                                                                      - MSDN [1]

This is even clear when you use the nikhilk's Web development helper with ie( can view request, response details) and check out the request [2] (check video) . It searches for those two files.

 
Here are the two files that are needed.
 
clientaccesspolicy.xml  

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="SOAPAction">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

crossdomain.xml

<?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="SOAPAction,Content-Type"/>
</cross-domain-policy>

Save both these files to the root of the domain where the service is hosted. If, for example, the service is hosted in http://fabrikam.com, then the file must be located at http://fabrikam.com/crossdomain.xml. Thanks to MSDN!


References

[1] http://msdn.microsoft.com/en-us/library/cc197955%28v=vs.95%29.aspx

[2]http://www.silverlight.net/learn/data-networking/introduction-to-data-and-networking/how-to-use-cross-domain-policy-files-with-silverlight

Check out the above video [2]  by Tim Heuer . It was really helpful!!!