views:

498

answers:

2

Issue:

An issue exists whereby I cannot access my Self Hosted ADO.NET Data Services from my RIA applications.

My services are hosted separately to the web projects with the Rich Internet Applications (RIA)s.

I need to enable access from separate Silverlight (and Flash) client apps.

From Silverlight I get an exception (see below) when I try to make a call to the ADO.NET Data Service (which is Self Hosted separately). This I believe to due to Silverlight forbidding the cross domain call.

*System.InvalidOperationException: An error occurred while saving changes. See the inner exception for details. ---> System.Data.Services.Http.WebException: Internal error at 'HttpWebResponse.NormalizeResponseStatus'. at System.Data.Services.Http.HttpWebResponse.NormalizeResponseStatus(Int32& statusCode) at System.Data.Services.Http.HttpWebResponse..ctor(HttpWebRequest request, Int32 statusCode, String responseHeaders) at System.Data.Services.Http.HttpWebRequest.CreateResponse() at System.Data.Services.Http.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) at System.Data.Services.Client.QueryAsyncResult.AsyncEndGetResponse(IAsyncResult asyncResult) --- End of inner exception stack trace --- at System.Data.Services.Client.BaseAsyncResult.EndExecuteT at System.Data.Services.Client.QueryAsyncResult.EndExecuteTElement at System.Data.Services.Client.DataServiceQuery`1.EndExecute(IAsyncResult asyncResult) at Curo.Silverlight.MainPage.<>c__DisplayClass1.<.ctor>b__0(IAsyncResult ar) at System.Data.Services.Client.BaseAsyncResult.HandleCompleted() at System.Data.Services.Client.QueryAsyncResult.AsyncEndGetResponse(IAsyncResult asyncResult) at System.Data.Services.Http.HttpWebRequest.ReadyStateChanged() System.Data.Services.Http.WebException: Internal error at 'HttpWebResponse.NormalizeResponseStatus'. at System.Data.Services.Http.HttpWebResponse.NormalizeResponseStatus(Int32& statusCode) at System.Data.Services.Http.HttpWebResponse..ctor(HttpWebRequest request, Int32 statusCode, String responseHeaders) at System.Data.Services.Http.HttpWebRequest.CreateResponse() at System.Data.Services.Http.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) at System.Data.Services.Client.QueryAsyncResult.AsyncEndGetResponse(IAsyncResult asyncResult)*

Notes:

From what I have read, it appears that cross domain access is forbidden with regards to ADO.NET Data Services, which may result in my having to take another approach to the data access e.g. using a pure REST Framework..?

"The problem of Cross Domain ADO.NET Data Services is more complex than it sounds and it hasn't been solved. I've discussed it with Microsoft for a while now and the reason that it doesn't work has to do with its using a browser level transport and that transport doesn't allow cross-site scripting."

See: http://forums.silverlight.net/forums/p/70925/170703.aspx#170703

I understand that I need may need to expose a ClientAccessPolicy.xml file which will define the access rules whilst restricting cross site scripting.

It is also noteworthy to mention that the RIA applications will be running on the same LAN.

Questions:

Is there a viable means for me to access the services from my RIA clients considering they will be running behind the same firewall? If so how?

How do I expose ClientAccessPolicy.xml from a Self Hosted ADO.NET Data Service exactly?

What way would you recommend proceeding in order to allow external access to my services? - Different REST Framework? - Host Services within same web project at the cost of separation? - Any other advice...

Thanks.

+1  A: 

I'm not sure I understand the full breadth of your problem, but at the very least, I would make sure I had a clientaccesspolicy.xml file and a crossdomain.xml file in the root folder of the service. It's important for the xml policy files to be in the root folder of the domain. For example, if your service is hosted in mycompany.com/services, the xml files need to be in the mycompany.com folder, not the services folder.

Here's an example of the ClientAccessPolicy.xml:

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

And here's an example of the crossdomain.xml:

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

I would recommend using both files for both flash and silverlight. Both files above will allow open access from all flash and silverlight apps, but that shouldn't be a problem if you're behind a firewall.

I had this exact problem in one of my behind-the-firewall silverlight apps and putting these files in place seemed to fix the problem. I would start with these files and go from there.

Ben McCormack
How do I expose ClientAccessPolicy.xml from a Self Hosted ADO.NET Data Service exactly?
StevenH
Sorry I missed your reply. Create a file called ClientAccessPolicy.xml just like the one I outlined above. Copy the paste from above if you wish. You need to go the root folder of where your service is hosted. For example, if your service is hosted at myPC.myCompany.com/Services/myservice, you need to drop the XML file in the folder of myPC.myCompany.com. That's where silverlight will look to find the file.
Ben McCormack
However, from reading your post above, it may still be more complicated than that. All I know to do at this point is to tell you where to drop the XML file.
Ben McCormack
Thanks for getting back to me. I exposed of the Policy files via a [WebGet] Service call as the data service is self hosted. There appears to be no way to expose ADO.NET DataServices Cross Domain.
StevenH
A: 

"The problem of Cross Domain ADO.NET Data Services is more complex than it sounds and it hasn't been solved. I've discussed it with Microsoft for a while now and the reason that it doesn't work has to do with its using a browser level transport and that transport doesn't allow cross-site scripting."

See: http://forums.silverlight.net/forums/p/70925/170703.aspx#170703

The cross domain policy is required by (as shown in the answer by Ben McCormack above).

By utilizing Yahoo pipes which is set up to allow cross domain access to aggregated feeds, you may be able to consume and external ADO.NET Data Services (formerly Astoria, now OData) from within a Silverlight application.

You will most likely lose the fidelity of querying the dataset that Odata gives you, but this could be recreated in the yahoo pipes.

The issue was not with the ADO.NET data services (OData), its was with Silverlight as does not allow cross domain calls.

StevenH