If you have an on-premise CRM server you can get around the cross-domain restrictions by putting a ClientAccessPolicy.xml file in the root of the CRM web application (See Markus Konrad's post on creating the policy file), but CRM online won't let you upload a ClientAccessPolicy, so you have to be a little more clever. One method is to just create a proxy to pass all the requests to the CRM server.
Creating a proxy for CRM SOAP requests
A quick note: This works for the SOAP Organization service and the example at the end of this post only uses the SOAP service. I'm not sure if a similar proxy would work for the REST endpoint (Given the REST endpoint's limitation I rarely use it anyway).
To get web-service requests to go from a Silverlight application w just need a few things:
1. Create an aspx page in the web project that's hosting the Silverlight app that will act as our proxy.
2. Program the proxy page to forward all posted requests to the CRM Online web-service endpoint.
3. Authenticate against CRM Online and attach the LiveId security token to each request.
4. Configure the Silverlight app to point to the proxy page.
Steps 1 and 2 are actually pretty straightforward once you pull out fiddler and figure out what the soap requests work like. Step 3 is the complicated bit but the sample code in the CRM SDK provides an example of authenticating against CRM Online (see sdk\samplecode\cs\wsdlbasedproxies\online). Once you've authenticated and have the security token you can just inject the token right into the header of the SOAP request.
I've built an example application which you can download here. It's just a simple Silverlight application that makes create, retrieve, update, delete, and execute request to CRM Online using the proxy described above.
To try it out just update the constants defined at the top of Proxy.aspx.cs:
//Update these constants to match your CRM Online accountconst string host = "orgName.api.crm.dynamics.com";const string userName = "erik.pool@example.com";const string password = "Password";
Also note the GetOrganizationService method in the Silverlight app. If the current page is running on "localhost" it assumes you're debugging and points the org service url at the proxy.aspx page. This way the same silverlight app works on my dev machine and when it's deployed to CRM Online.
if (href.Contains("localhost")){Uri baseUrl = new Uri(href, UriKind.Absolute);orgServiceUrl = new Uri(baseUrl, "SoapProxy/Proxy.aspx");}else{orgServiceUrl = new Uri(location.GetProperty("protocol") + "//" + location.GetProperty("host") + "/xrmservices/2011/organization.svc/web");}
Download the source code here.
-Erik