Using web client in Silverlight - silverlight

I am having a heck of a time calling a RESTful service from within silverlight. I am encountering this error:
{System.Security.SecurityException ---> System.Security.SecurityException: Security error.
at System.Net.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.BrowserHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
at System.Net.AsyncHelper.<>c__DisplayClass2.<BeginOnUI>b__0(Object sendState)
--- End of inner exception stack trace ---
at System.Net.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)
at System.Net.WebClient.OpenReadAsyncCallback(IAsyncResult result)}
Which seems to be a popular error when using the webclient. I have put in place a 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 path="/" include-subpaths="true" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
and I have watched the silverlight in fiddler and it does make a request to the web site and does get a 200 status back.
public void login(string userName, string password)
{
WebClient client = new WebClient();
Uri uri = new Uri(serverURI + "/clientaccesspolicy.xml");
client.OpenReadCompleted += new OpenReadCompletedEventHandler(login_Complete);
client.OpenReadAsync(uri);
}
private void login_Complete(object sender, OpenReadCompletedEventArgs e)
{
byte[] buffer = new byte[e.Result.Length]; //crashes here with exception
...
}
I am more or less out of ideas. Anybody know what I'm doing wrong? Is there some issue with running the silverlight directly from a file:// uri?
Update: I deleted the clientaccesspolicy.xml file and kept just the crossdomain.xml file in place and bingo everything worked. That makes me believe that the error is in the clientaccesspolicy file but I copied that directly from microsoft. What gives?

I just spent 3 hours looking into this very issue. The cross domain access policy and client access policy files were a dead-end for me. Nothing would work. Then finally I ran into a post on the Silverlight.net forums by a Microsoft employee that helped me fix the issue.
The answer, at least in my case was the test webpage that Visual Studio generates when you create a new Silverlight application.
Basically you get two options when you start a Silverlight project. The first option will generate an html page dynamically when you run your application. The second option will create a separate ASP.NET project that will host your Silverlight application. If you choose the first option (dynamic test page) you will not be able to do any cross domain requests, even if both your projects are on the same box it will somehow consider this a cross domain call and fail (I am not sure why)
Create another Silverlight project, choose the second option, and move your XAML files in. That should fix your issue.

You can't request content from a website if your Silverlight application is running from a file:// URL.
For more information, see URL Access Restrictions in Silverlight.

Mmm...
Try with this cross domain file
<?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 include-subpaths="true" path="/"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>

X-Cubed is correct, you cannot do cross-domain requests from file://, as Adam Berent pointed out, this means if you use the TestPage generated by visual studio your network requests will fail.
A workaround is to launch the TestPage using Chiron (usually used for dynamic languages) to serve it (because then the access is on http://) or off a development web server.
The catch is you actually have to attach the debugger manually to the browser in order to debug with networking (you can't just hit F5.)

Related

Silverlight clientaccesspolicy.xml

We have Silverlight Application with RIA web service. URL: https://mysite.mydomain.com/services/mysitewebservice.svc
Also, we have a Sharepoint (SharePoint 2013) site hosted in separate domain. URL: https://mysharepointsite.mydomain.com
The Silverlight RIA service is called in SharePoint Silverlight Web Part.
I placed the "clientaccesspolicy.xml" file in the Silverlight root site (URL: https://mysite.mydomain.com/clientaccesspolicy.xml) and I can view this file in IE v11 browser. Compatibility view is ON.
<?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 path="/" include-subpaths="true"/>
</grant-to>
</policy>
But calling the service in SharePoint Site SL Web Part. an exception error still occurs.
"Load operation failed for query 'GetMyData'. An error occurred while trying to make a request to URI 'https://mysite.mydomain.com/services/mysitewebservice.svc/binary/GetMyData?category=sales'. 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."
I read bunch of forums and articles but they all points to placing the clientaccesspolicy.xml in root site.
What is missing. Please help.

getting crossdomain error in silverlight and clientaccesspolicy 304 error

I need to write some data to the DB from a Silverlight 4 application.
I'm using a Silverlight Enabled WCF Web Service. I've published it to IIS7 and added a ClientAccessPolicy.xml file to the inetpub/wwwroot (among other places) so I can access localhost/ClientAccessPolicy.xml just fine. I also added crossdomain.xml just in case.
I also have a Silverlight4 client app which accesses this service and runs through VS2010 on development server.
When trying to invoke a method in the WebService I'm getting a crossdomain error although I have a crossdomain policy in place and the web service is working fine.
When using Fidler I see I'm getting a 304 error when the client app is trying to access the clientaccesspolicy.xml
If I also publish the client app to IIS7 (both under port 80), I can run it using a browser on the same machine with no problem. But when I try to access it on a different machine, I again get a crossdaomain error.
I tried everything but I can't find an answer for this problem anywhere! Please help!!
This is what my ClientAccessPolicy.xml looks like:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="SOAPAction">
<domain uri="http://*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
I have struggled with this misleading error "crossdomain error" before and after reading your situation I can tell for sure that ClientAccessPolicy.xml configuration is not the issue here you should look elsewhere.
few things i would do
Check my client config & web service configs(double check endpoints, behaviours and finally binding protocols) on the silverlight app.
Enable error logging for your wcf service.
Make sure you are passing the right authentication token to your web service (enable anonymous authentication for the web application hosting WCF service)).

Silverlight Security Issue: Self Signed Certificate

I am using silverlight 4 application, in two scenarios.
Scenario 1: Silverlight and RPC on same machine
Being run hosted on a web page on the file system, silverlight XAP is also on the file system:
C:\Silverlight\FSSilverlightApp\bin\Debug\SilverlightApplication2TestPage.html
Connecting to a web site on localhost, being accessed:
https://localhost/rpc/someMethod
These are two separate URI's so the browser detects and immediately requests (track via fiddler):
https://lcoalhost/clientaccesspolicy.xml
sucessfully returns:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="http://*"/>
<domain uri="https://*" />
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
The application is then able to make the rpc requests (observed via fiddler)
Everything is fine. If i change the remote host to the local machine name instead of localhost, that works fine as well.
Scenario 2: Silverlight on local machine and RPC is remote
In this scenario, I am using a different desktop to access the same RPC server used in scenario 1.
Silverlight starts up, and no request to: clientaccesspolicy.xml is made
Fiddler shows a ton of https tunnels being established, but no commuinication between my machine and the remote server.
The following security exception is returned:
System.Security.SecurityException ---> System.Security.SecurityException: Security error.
at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResultasyncResult)
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(ObjectsendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass2.<BeginOnUI>b__0(Object sendState)
--- End of inner exception stack trace ---
at Microsoft.FSharp.Control.WebExtensions.AsyncGetResponse#1781-1.Invoke(Exception _arg1023)
at Microsoft.FSharp.Control.AsyncBuilderImpl.callA#736.Invoke(AsyncParams`1 args)
I assume this is an IE configuration issue. I tried setting the machine in scenario 1, as a trusted site inside of internet explorer and that didn't seem to work... This must be a self signed or mismatched certificate issue. Any thoughts?
Using: IE 8 and Windows 7
Thoughts?
I used Fiddler to sit in between the sliverlight client and the server. IN order to get that to work properly I needed to export the fiddler certificate (tools\fiddlerOptions\https) and install it locally as the root certificate authority.

SL 4 and WCF DataService: InvalidOperationException -> SecurityException

you will think: "This problem has been solved many, many times. So why doesn't he use Google?" Please, believe me, I tried everything. I'm dealing with this problem since last week. I read many blogs and searched the MSDN. But I don't get it.
So here is the problem. There is one Silverlight 4 app and a WCF DataService, both are running on localhost.
This is the code. Nothing special I guess.
private void InitializeData()
{
var query = (from item in ObjCtx.TestTgt
select item) as DataServiceQuery<TestTgt>;
Debug.Assert(query != null, "'query' is null");
query.BeginExecute(OnLoadDataFinished, query);
}
private void OnLoadDataFinished(IAsyncResult ar)
{
try
{
var query = ar.AsyncState as DataServiceQuery<TestTgt>;
Debug.Assert(query != null, "'query' is null");
var res = query.EndExecute(ar).ToList();
Data.Data = new ObservableCollection<TestTgt>(res);
}
catch(Exception ex)
{
Data.StateDescription = String.Format("Exception occured.{0}{0}{1}", Environment.NewLine, AgExMsgFormatter.GetExText(ex));
}
}
In OnLoadData at this line: var res = query.EndExecute(ar).ToList(); the following exception occures.
Exception occured.
[EXCEPTION]
[TYPE:] 'InvalidOperationException'
[MESSAGE:] 'An error occurred while processing this request.'
[CALLSTACK:]
at System.Data.Services.Client.BaseAsyncResult.EndExecute[T](Object source, String method, IAsyncResult asyncResult)
at System.Data.Services.Client.QueryResult.EndExecute[TElement](Object source, IAsyncResult asyncResult)
at System.Data.Services.Client.DataServiceRequest.EndExecute[TElement](Object source, DataServiceContext context, IAsyncResult asyncResult)
at System.Data.Services.Client.DataServiceQuery`1.EndExecute(IAsyncResult asyncResult)
at SimpleGrid.SimpleGridVm.OnLoadDataFinished(IAsyncResult ar)
[INNEREXCEPTION]
[TYPE:] 'SecurityException'
[MESSAGE:] ''
[CALLSTACK:]
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Data.Services.Http.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Data.Services.Client.QueryResult.AsyncEndGetResponse(IAsyncResult asyncResult)
[INNEREXCEPTION]
[TYPE:] 'SecurityException'
[MESSAGE:] 'Security error.'
[CALLSTACK:]
at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClass5.b__4(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass2.b__0(Object sendState)
[/INNEREXCEPTION]
[/INNEREXCEPTION]
[/EXCEPTION]
As authentication mode I want to use Windows. Both are configured for this in IIS. The web service is running and is delivering the correct data.
So what am I missing? I thought that this should work. Any help would be appreciated.
Regards
your issue looks like a cross domain error: A silverlight app is not allowed to perform cross domain webservice calls by default. It means that if your cassini hosted SL app (domain localhost:4314 for example) attempts to access a WCF service on the domain localhost, the call will fail with a security exception.
You can easily catch the issue by using fiddler or the network tab of firebug (on firefox): The app first attempt to access a file named "clientaccesspolicy.xml" on the webservice domain root. This file defines a policy on the WCF server which authorize cross domain calls on the server.
Here is an exemple of crossdomain policy file, which allow any SL apps to access any webservices on this domain:
<?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>
<policy >
<allow-from http-methods="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
However You can be a little more specific. More information is available on MSDN:
Hmm, ok that's suprising but I got it. The problem is not the authentication or something like this. It's the debugger. The web service is not hosted on the web site of the Silverlight application. So the web service calls are failing.
When loading the deployed site in a browser everything works absolutly fine. For me, it appears somekind of strange, but perhaps someone can give me a good explanation for this behavior.
But this brings up another problem. How do I debug a Silverlight application, when it references an external web service. Perhaps I will open a seperate thread for this.
Regards
Here my solution:
The RIA service runs, exactly as you said, on localhost.
The error comes when the Silverlight project is the statup project.
The RIA service is called in that case in the context of a different
web page.
Visual Studio Debugger warns about that, but the popup is often
checked to "Don't show".
The solution is:
Set the the Web Project in the solution as startup project.
Set the generated, TestPage.html as start page.
And the RIA Service works.
You probarly need to start Visual Studio as Administrator

Silverlight Crossdomain

I've seen a lot of links to MSDN and "works on my machine!" answers so I'd like to ask my question with the exact steps to duplicate what I'm doing. Because we are using an already existing webservice, I'm asking with the context of having a webservice hosted outside of my project, unlike many of the tutorials and videos online. So here goes:
*** Create a new ASP.NET webservice project.
It will come with an existing Service.asmx file exposing a "HelloWorld" web method.
View in browser, hit the "Invoke" button. It should work returning the "Hello World" string.
On my machine, the URL is: "http://localhost:15511/WebSite5/Service.asmx"
*** Start a new instance of Visual Studio, create a Silverlight Web Application Project.
*** Stick a single button on there with an event handler to call the web service. I personally nuke the Grid and use a simple StackPanel. eg.
<UserControl x:Class="SilverlightApplication1.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<StackPanel>
<Button Click="Button_Click">
<Button.Content>
<TextBlock Text="Test"/>
</Button.Content>
</Button>
</StackPanel>
</UserControl>
Add the web reference, using statement and event handler for the Button_Click:
private void Button_Click(object sender, RoutedEventArgs e)
{
ServiceSoapClient client = new ServiceSoapClient();
client.HelloWorldCompleted += (object s, HelloWorldCompletedEventArgs ea) => {
MessageBox.Show(ea.Result);
};
client.HelloWorldAsync();
}
Run the Silverlight Application. In my case I'm going to my Silverlight Test Page at:
http://localhost:15558/SilverlightApplication1TestPage.aspx
Run and of course it blows up because of crossdomain issues. So next add the clientaccesspolicy.xml file with the following to the root of your web application hosting the service:
<?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>
This should open things up since it's got a wildcard for headers, uris, and resources, right?
Run again and you get an error:
An error occurred while trying to make a request to URI 'http://localhost:15511/WebSite5/Service.asmx'. 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.
So question: is there a secret to the clientaccesspolicy file? One could alternately try with the crossdomain.xml but it gives a similar result.
I've encountered this problem (SL v5.0 and Visual Studio 2010), what fixed it for me is that I went into the Silverlight project properties >> Silverlight tab and selected "Require elevated trust when running in-browser"
I've had this same problem a couple of times. In the past I've solved this by using the Web App as start up, but it looks like you've already done that.
My post on the subject: http://www.donnfelker.com/silverlight-cross-domain-issue/
Make sure that you put the clientaccesspolicy.xml file in the root of IIS web directory e.g.
C:\Inetpub\wwwroot\clientaccesspolicy.xml
This will make sure that it is accessible directly at http:///clientaccesspolicy.xml
I was getting the same error and I resolved it doing the above steps.
Client Configuration
Maybe your ServiceReferences.ClientConfig for your Silverlight client is pointing to the wrong URL?
Also, check the location of your cross-domain policy file. This MSDN article has more information.
Locally Running Silverlight
Additional note for running Silverlight locally (Vista Sidebar, for example). As reported in this blog entry, "Silverlight cannot use any network provider, when running locally." The workaround is to use javascript to interface to the web service in this situation.
Something that worked for me began with what I found on the silverlight forums here. It essentially asked if I could even get to my clientaccesspolicy.xml or crossdomain.xml from localhost (http://localhost/clientaccesspolicy.xml). When I tried to navigate there, I couldn't so I simply found the code for both of them (also within the aforementioned thread), and copy-pasted over the code inside of those files existing in my inetpub\wwwroot\ directory (I opened them up using Notepad++). The weird part was the code didn't change at all , and yet, it works! Hope that helps someone! This was extremely strange.
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 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="*"/>
</cross-domain-policy>
Be blessed!
-sf
Have you tried fiddler when using this through IE, you might be able to see the traffic silverlight is causing, such as which cross policy files it is looking for?
I modified my Internet explorer settings. The website runs on a intern webserver so I added it in the Iexplorer Trusted Sites list. (Tools->Internet Options->Security->Sites).
Then I changed the security level and enabled cross domains. Done, Works but took me while to find the solution.
Best,
Jeppen
You have to be aware of situation that when you reference to your service inside your project there 'll be created file "Reference.ClienConfig" and there is:
**
<endpoint address="http://localhost:57675/Servis.asmx" binding="basicHttpBinding"
bindingConfiguration="ServisSoap" contract="ServiceReference1.ServisSoap"
name="ServisSoap" />
**
Make sure that your page is still using the same port (for example here is 57675). By default your localhost 'll get random port, so you have to change it to be static number and not Dynamic. (Right click on asp.net project/Tab Web/Specific port /type number
Hope it helps
I ran into something like this and adding a ServiceHostFactory fixed my issue. The cross-domain policy file alone did not fix it.
class MyHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
MyHost customServiceHost =
new MyHost(serviceType, new Uri("[Your URL goes here]",UriKind.Absolute));
return customServiceHost;
}
}
class MyHost : ServiceHost
{
public MyHost(Type serviceType, params Uri[] baseAddresses) base(serviceType, baseAddresses)
{ }
protected override void ApplyConfiguration()
{
base.ApplyConfiguration();
}
}
You also have to add Factory="MyHostFactory" in the tag that defines your service
The problem could be that your development server is not able to serve the xml file, try this - explicitly make it available through WebGet
[ServiceContract]
public interface ICrossDomainService
{
[OperationContract]
[WebGet(UriTemplate = "ClientAccessPolicy.xml")]
Message ProvidePolicyFile();
}
and then the ProvidePolicyFile() can be
public System.ServiceModel.Channels.Message ProvidePolicyFile()
{
FileStream filestream = File.Open(#"ClientAcessPolicy.xml", FileMode.Open);
// Either specify ClientAcessPolicy.xml file path properly
// or put that in \Bin folder of the console application
XmlReader reader = XmlReader.Create(filestream);
System.ServiceModel.Channels.Message result = Message.CreateMessage(MessageVersion.None, "", reader);
return result;
}
It worked in my pc successfully, you can place your
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 path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
both your project directory and your webservices root.
I was facing the same problem and take more than 3 days to figure out the Problem. I notice also when I was calling the internet Cloud Service WCF from a Silverlight app hosted in another web server it just shows Cross-Domain Errors.
After looking into some posts I didn't solve the problem, even putting cross-domain.xml and clientaccesspolice.xml files in service root directory.
So I just try to instead of using http://example.com I just change it to secure https://example.com and it just worked fine. The cross-domain errors disappears. service was called without problems.
Check which project is set default.
It should be the web project that should be set default and not the silverlight project.

Resources