R – Self Hosted ADO.NET Data Services, comsuming from an external Silverlight application

client-serversilverlightwcf-data-services

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.EndExecute[T](Object source, String method, IAsyncResult asyncResult)
at System.Data.Services.Client.QueryAsyncResult.EndExecute[TElement](Object source, IAsyncResult asyncResult)
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.

Best Answer

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">
<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.

Related Topic