Accessing SharePoint Web Services over Silverlight - silverlight

I have a problem to access SharePoint Webservice over Silverlight.
An error occurred while trying to make a request to URI
'http://sample:8000/_vti_bin/Authentication.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.
Please see the inner exception for
more details.
Some questions:
How do I correctly deploy clientaccesspolicy.xml over Sharepoint Designer? Simply open site in designer, add file and then publish?
The site where clientaccesspolicy.xml should be deployed use forms authentication. I wasn't able to use Sharepoint Designer to publish there. Because of that, I created new zone for this site, which use Windows Authentication and published clientaccesspolicy.xml there. Both use same content database, didn't ?
If clientaccesspolicy.xml will be published, how can I allow this file be accessed anonymously?
Regards
Anton Kalcik

Here answers to my question 1. and 2.:
In Sharepoint Designer you open the site over: File -> Open Site -> In text field "Site name:" type URL of your site. Than drag & drop clientaccesspolicy.xml in root of your site.
If you have Form Authentication, you don't need for this step create new zone (but for some reasons it can be useful). You simply open web browser and type URL of your site. Then fill up text fields (always with user that have administrator privileges) and check "Sign me in automatically". After that will Sharepoint designer use this credentials for specified URL.
If you can help me with question Nr. 3, or you have some other solution, how can I access clientaccesspolicy.xml from Silverlight, post it!

The way we handled this on our project was to use an HTTP Handler. We put the clientaccesspolicy.xml file in the _layouts directory (which is shared across sharepoint sites) using a feature (you can also just manually copy it there).
Then we added our HTTP handler to the web.config handlers section. In our handler we check to see if the request is for /clientaccesspolicy.xml and if so we rewrite the path:
if (path.ToLowerInvariant() == "/clientaccesspolicy.xml")
{
HttpContext.Current.RewritePath("/_layouts/clientaccesspolicy.xml");
}
I'm not sure if this will bypass the security so it might not fully address your issue. But at least it gives you a method to access this file.

That is fine.
It should be, provided you haven't setup a whole new site somehow.
It shouldn't be as that would be a security risk. If you need to authenticate via WindowsAuth for the services so should you for the clientaccesspolicy.xml.

Keep in mind that clientaccesspolicy.xml must be at the domain root. In your example it would have to availble from http://sample:8000/clientaccesspolicy.xml. If you can't open it from your browser at that URL, your Silverlight client won't find it either.
The easiest way to get the file in the right place is to just copy it there via FTP or explorer. The file should be available to anonymous users (read only of course).

I find more realeable way to implement sharepoint httpHandler: it returns all content of clientaccesspolicy.xml himself
public void ProcessRequest(HttpContext context) {
if (context.Request.Path.ToLowerInvariant() == "/clientaccesspolicy.xml") {
context.Response.Write(#"<?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>");
}
}

Related

Clientaccesspolicy.xml to be found under a port on Tomcat

I am running a Tomcat 6 server configured to use port 7787.I have to post data from a Silverlight app to a servlet running on this server.Ofcourse this is crossdomain so it requires me to have clientaccesspolicy.xml in the root.
I have seen various questions about this here and on the web and all have the same answer.To put the xml in webapps/ROOT.This works if I try to access the xml via
http://somedomain/
However since the servlet is running on port 7787 I have to post to somedomain:7787 and thus Silverlight tries to find the xml under
http://somedomain:7787/
This is unsuccesfull.
I am sure that Silverlight does indeed check somedomain:7787 for the xml as I used Firebug to confirm it.Is there anything in Tomcats configuration I can change or somewhere else I can place the xml so Silverlight can find it under port 7787.Or is there perhaps something I can change on the Silverlight side where the POST is being done?
On Windows machine simply copy the two security files to Tomcat's webapps/ROOT folder
As long as you can get response from ...:7787/crossdomain.xml, anyway solution is OK.
Looks like Silverlight only cares about the response.
I created a Silverlight client and it is OK to get response both from WCF service and Tomcat.

Where to place ClientAccessPolicy.xml for Local WCF Service?

I'm trying to create a basic WCF Service and Silverlight client.
I've followed the following tutorial: http://channel9.msdn.com/shows/Endpoint/Endpoint-Screencasts-Creating-Your-First-WCF-Client/
Since Silverlight 4 was incompatible with the WSHttpBinding, I changed it to BasicHttpBinding.
Unfortunately I keep getting this error now: "An error occurred while trying to make a request to URI'**'.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."
I placed clientaccesspolicy.xml in the root directory of the WCF project (which is in the same solution as the Silverlight client). This did not solve the problem.
What do I need to do?
I thnk this is duplicate question :
here are some links , see if any of them helps u :
link text
link text
link text

Deployed silverlight enabled WCF Service Stops Working when development server is stopped

I have a silverlight business aplication that gets data from silverlight enabled webservice.
When I run the application in dev environment, it works fine.
when i deploy the application and the Asp.net web development server is working, then to the application works fine.
But when I stop the development server, the application can't access a service.
My questions are:
When I deploy a silverlight business application, doesn't the service get deployed and get started.
The endpoint address in my ServiceReferences.Clientconfig file is endpoint address="http://localhost:9702/MyWebservice.scv. Do I need to change this?
The enpoint address in the web.config is blank.
Appreciate your help
Because the WCF client code is declared as a "partial" class, what I've been doing to this point is creating another c# partial class file to host a GetClient() method on it. You'll notice that the code is taking into account the port that the service is on... in a few of the environments that I've posted or will be posting to, as well as the development environment, the application is not always on port 80.
Namespace Project.Service
{
public partial class ServiceClient
{
public static ServiceClient GetClient()
{
return new ServiceClient("CustomBinding_Service",
new System.ServiceModel.EndpointAddress(new Uri(string.Format("{0}://{1}:{2}/Services/Service.svc",
Application.Current.Host.Source.Scheme, Application.Current.Host.Source.Host, Application.Current.Host.Source.Port), UriKind.Absolute)));
}
}
}
Hope this helps someone!
Yes you are going to want to change your endpoint address. I recommend doing it in the silverlight code when creating the connection to the WCF service. The service itself lives on the web server, whereas the silverlight application lives on the clients computer. If the web server stops, the web service stops but the silverlight app can keep running.
edit:
To do this in code, as long as the path is always in the same domain as the app you can use do like so:
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None) //Use whatever security you need here
{
MaxReceivedMessageSize = int.MaxValue,
MaxBufferSize = int.MaxValue
};
Client client = new Client(binding, new EndpointAddress(new Uri(Application.Current.Host.Source, "../MyService.svc")));
Thanks so much for your help. I tried your approach to create the client code but that didn't work. And that's because the problem seems to be somewhere else.
So I installed fiddler to see the traffic.
Fiddler showed that the service was being accessed but the http response code was 302 showing that there was some redirection involved.
The address of my application is like this http:///Silverlightapp/(S(oirppxrwzhlf2a2vbia1ui45))/Default.aspx#/Home and it is hosted on IIS 6.
So I had to employ a workaround by installing the service on machine with IIS7 (and there was no session id involved like in the above url).I still kept the silverlight application hosted on IIS 6.
Anyway, in summary, to anyone who reads the thread, I did the following to troubleshoot and solve issue(temporarily)
Changed the end point address in the ServiceReferences.ClientConfig file. When you add the service using discover option in VS, the endpoint address is of the localhost and this must be changed.
Registered the service model using ServiceModelReg -i command. (this solved my problem that my applicaiton was only working from development server and not IIS)
-Put the CrossDomain and ClientAccessPolicy files in c:]inetpub\wwwroot folders.
-Used fiddler to look at http response codes. I had to do no configuration in fiddler.
Changed the binarymessageEncoding to textMessageEncoding iin the web.config file of the silverlight web project that also hosted the ecf service. I did this becasue adding a silverlight enabled wcf service creates a custom binding configuration in the web.config file by default uses binary encoding. I needed text encoding to see errors in fidder. But this didn't help much becasue I only saw the name of the operation in the Inspector>xml tab in fiddler. This was the same even after my issues was resolved by workaround.
Thanks for the help
Don't do it in code. Otherwise you won't be able to change it later without recompiling the application (when the address will need to change, perhaps years down the road when you've lost the source code :)
Change the address in ServiceReferences.ClientConfig to where the service is actually hosted... e.g. http://example.com/myVdir/MyWebservice.svc
If later on you need to change the address without recompiling:
- Open the .xap file (it's just a zip file with a different extension)
- Find the .ClientConfig file and change the address
- Put it back together as a .zip file and rename to .xap
Also, I can't remember anymore whether the .ClientConfig supports relative addresses (e.g. just "MyWebService.svc"), but if it does it may be a good solution as well.

Prevent Silverlight xap from being cached by proxy server

The company I work for has proxies/WAN accelerators between our international sites to cache Intranet web content. I have a Silverlight application being hosted on a server at one location, but being accessed by clients in another location. When the users access the web page hosting the Silverlight app, they get the stale xap file being cached by the proxy and not the latest version from the server. Local users always get the latest xap as their requests are not going through a proxy.
I've tried the various header/metadata techniques mentioned elsewhere to prevent caching, and the containing web page itself is being served up fresh, but I still get the old .xap file. Short of getting our IT admin to disable proxy caching for my site, is there anything I can do make sure the latest xap file get retrieved from the server instead of the proxy? The containing page is ASP.NET.
What I do is just add a querystring at the end of the path to the xap file. Then when you change the querystring variable, the proxies etc. should see it as a request to a new file. So far this has worked fine for me.
So basically, when embedding an .xap in a straight-up HTML file, you would do this:
<param name="source" value="ClientBin/SilverlightApplication1.xap?cachepreventer=whatevervalue"/>
And then when you deploy a new version, just change "whatevervalue" to something else.
EDIT
If you need to use this technique in many places in your app I would read the querystring value from config and just write it to the page using asp.net. That way you only need to update it in one place when you deploy.
If you want to make sure every time the xap file is retrieved and you don't want to worry about it - just use
<param name="source" value="ClientBin/YourSilverlightapp.xap?<%=Guid.NewGuid().ToString() %>"/>
of course - this lends itself to a heavier cache load. I do like the helper method above though if you only want changes to be propagated to the client.

Using a subdomain to identify a client

I'm working on building a Silverlight application whereas we want to be able to have a client hit a url like:
http://{client}.domain.com/
and login, where the {client} part is their business name. so for example, google's would be:
http://google.domain.com/
What I was wondering was if anyone has been able, in silverlight, to be able to use this subdomain model to make decisions on the call to the web server so that you can switch to a specific database to run a query? Unfortunately, it's something that is quite necessary for the project, as we are trying to make it easy for their employees to get their company specific information for our software.
Wouldn't it work to put the service on a specific subdomain itself, such as wcf.example.com, and then setup a cross domain policy file on the service to allow it to access it?
As long as this would work you could just load the silverlight in the proper subdomain and then pass that subdomain to your service and let it do its thing.
Some examples of this below:
Silverlight Cross Domain Services
Silverlight Cross Domain Policy Helpers
On the server side you can check the HTTP 1.1 Host header to see how the user came to your server and do the necessary customization based on that.
I think you cannot do this with Silverlight alone, I know you cannot do this without problems with Javascript, Ajax etc. . That is because a sub domain is - for security reasons - treated otherwise than a sub-page by the browsers.
What about the following idea: Insert a rewrite rule to your web server software. So if http://google.domain.com is called, the web server itself rewrites the URL to something like http://www.domain.com/google/ (or better: http://www.domain.com/customers/google/). Would that help?
Georgi:
That would help if it would be static, but alas, it's going to all be dynamic. My hope was to have 1x deployment for the application, and to use the http://google.domain.com/ idea to switch to the correct database for the user. I recall doing this once when we built an asp.net website, using the domain context to figure out what skin to use, etc.
Ates: Can you explain more about what you are saying... sounds like you are close to what I am trying to come up with. Have you seen such a tutorial for this?
The only other way I have come up with to make this work is to have a metabase that when the user logs in, it will switch them to the appropriate database as required... was just thinking as well that telling Client x to hit:
http://ClientX.domain.com/ would have been sweeter than saying to hit http://www.domain.com/ and login. It seemed as if they were to hit their name, and to show it personalized for them right from the login screen would have been much more appealing for the client base.
#Richard B: No, I can't think of any such tutorial that I've seen before. I'll try to be more verbose.
The server-side approach in more detail:
Direct *.example.com to the same IP in your DNS settings.
The backend app that handles login checks the Host HTTP header (e.g. the "HTTP_HOST" server variable in some platforms). That would contain the exact subdomain.example.com that the client used for reaching your server. Extract the subdomain part and continue...
There can also be a client-side-only approach. I don't know much about Silverlight but I'm assuming that you should be able to interface Silverlight with JavaScript. You could read document.location with JavaScript and pass it to your Silverlight applet, whereon further data fetching etc. logic would rely on the subdomain that was passed in by JavaScript.
#Ates:
That is what we did when we wrote the ASP.Net system... we pushed a slew of *.example.com hosts against the web server, and handled using the HTTP headers. The hold-up comes when dealing with WCF pushing the info between the client and the server... it can only exist in one domain...
So, for example, when you have {client}.example.com and {sandbox}.example.com, the WCF service can't be registered to both. It also cannot be registered to just *.example.com or example.com, so that's where the catch 22 is coming in at. everything else I have the prior knowledge of handling.
I recall a method by which an application can "spoof" another domain name in certain instances. I take it in this case, I would need to do such a configuration? Much to research yet I believe.

Resources