Cross Domain Policy VWD express

807
5
12-29-2010 07:15 AM
DavidLamb
New Contributor III
Hello all,

I'm learning about using the ArcGIS Silverlight API and am creating a Silverlight 4 Business Application with WCF RIA Services.  I would like to use a base map from this service http://sunlight.wygisc.uwyo.edu/ArcGIS/rest/services/Base_Data/MapServer.  I'm assuming it is public.  Unfortunately everytime this loads I get an error about the cross-domain policy.  I'm using Visual Web Developer 2010, .NET 4, Silverlight API 2.1.  I've done this before without the error but with a different ArcGIS REST service from a different server.  Do I need to add the crossdomain.xml file?  If so where would I do that for VWD express?

Any help would be appreciated.

Cheers,
David
0 Kudos
5 Replies
AliMirzabeigi
New Contributor
You would need to place the clientaccesspolicy.xml file at the root of the domain where the  service is hosted. More information here. An alternative approach would be using a proxy page (.ashx file) for the services you are not hosting or have no access to place this file.
0 Kudos
DavidLamb
New Contributor III
I don't have access to their servers/service.  I found their crossdomain file at http://sunlight.wygisc.uwyo.edu/crossdomain.xml.  It seems to provide access to their services.  Is there anything that would be prohibiting me from accessing it with silverlight.  I don't *think* there is anything wrong with my application since I was able to add a layer from another service and that worked fine. 

  <?xml version="1.0" ?>
  <!DOCTYPE cross-domain-policy (View Source for full doctype...)>
- <cross-domain-policy>
  <site-control permitted-cross-domain-policies="all" />
  <allow-access-from domain="*" to-ports="*" secure="true" />
  <allow-http-request-headers-from domain="*.wygisc.uwyo.edu" headers="SOAPAction" secure="false" />
  </cross-domain-policy>

They don't have a clientaccesspolicy.xml file from what I could tell.

Thanks for your response.

Cheers,
David
0 Kudos
AliMirzabeigi
New Contributor
From what I see in the crossdomain.xaml file you posted the map service your are trying to access only provides HTTPS sources permission or any domain containing ".wygisc.uwyo.edu" at the end of their URL therefore; you need a proxy page to access the map service. I tried using ESRI's demo proxy page in which we generally use in our SDK samples and it worked; see the code snippet below:

<esri:ArcGISTiledMapServiceLayer ID="David'sLayer" 
      ProxyURL="http://serverapps.esri.com/SilverlightDemos/ProxyPage/proxy.ashx"
      Url="http://sunlight.wygisc.uwyo.edu/ArcGIS/rest/services/Base_Data/MapServer" />
0 Kudos
DavidLamb
New Contributor III
Thanks for your help, that worked for me.  I'll add a proxy to my application.

Cheers,
David
0 Kudos
DavidLamb
New Contributor III
If anyone else is interested, the link above doesn't work, but you can download the javascript api proxy page here:  http://resources.esri.com/help/9.3/arcgisserver/apis/javascript/arcgis/help/jshelp_start.htm#jshelp/...

I converted this over to vb.net since that is what I'm working in, minus the proxy.config file since I'm not working with tokens for my learning application.  I also restricted the proxy to working with a single uri.  I don't know if that is the best way to handle it, but in my readings it sounded like a good idea to limit what the page can be used for.  I used a generic handler and here is the code for the ProcessRequest Sub.  In your map xaml as Ali has done you can add a proxy tag, but just set it to "http://localhost:*current port number*/generichandler.ashx"

Your *current port number* may change.  Or if you have a server you can host your handler there and change the url accordingly.

   
 Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

        Dim response As HttpResponse = context.Response


        Dim uri As String = HttpUtility.UrlDecode(context.Request.Url.Query.Substring(1))

        If Not uri.Contains(urlStr) Then

            response.StatusCode = 500
            response.StatusDescription = "Wrong url detected"
            response.Write("This proxy page is dedicated to a single url.")
            response.End()
            Return
        End If
        Dim req As System.Net.HttpWebRequest = DirectCast(System.Net.WebRequest.Create(uri), System.Net.HttpWebRequest)
        req.Method = context.Request.HttpMethod
        req.ServicePoint.Expect100Continue = False

        If context.Request.InputStream.Length > 0 Then
            Dim bytes(context.Request.InputStream.Length) As Byte
            context.Request.InputStream.Read(bytes, 0, context.Request.InputStream.Length)
            req.ContentLength = bytes.Length

            Dim contType As String = context.Request.ContentType

            If String.IsNullOrEmpty(contType) Then
                req.ContentType = "application/x-ww-form-urlencoded"
            Else
                req.ContentType = contType

            End If

            Using outputStream As Stream = req.GetRequestStream()
                outputStream.Write(bytes, 0, bytes.Length)
            End Using
        End If

        Dim serverResponse As System.Net.WebResponse = Nothing
        Try
            serverResponse = req.GetResponse()
        Catch webExc As System.Net.WebException

            response.StatusCode = 500
            response.StatusDescription = webExc.Status.ToString()
            response.Write(webExc.Response.ToString())
            response.End()
            Return

        End Try

        If Not serverResponse Is Nothing Then
            response.ContentType = serverResponse.ContentType
            Using byteStream As Stream = serverResponse.GetResponseStream()
                If serverResponse.ContentType.Contains("text") Or serverResponse.ContentType.Contains("json") Then
                    Using sr As StreamReader = New StreamReader(byteStream)
                        Dim strResponse As String = sr.ReadToEnd
                        response.Write(strResponse)
                    End Using
                Else
                    Dim br As New BinaryReader(byteStream)
                    Dim outb() As Byte = br.ReadBytes(serverResponse.ContentLength)
                    br.Close()

                    response.CacheControl = "no-cache"
                    response.OutputStream.Write(outb, 0, outb.Length)
                End If
                serverResponse.Close()
            End Using
        End If
        response.End()


    End Sub


Please let me know of any suggestions for improvement.

Cheers,
David
0 Kudos