In this article, we are going to see how we can access a Web Service from a Silverlight application.
- Making a Service available across domain boundaries
- Significance and best practices of the “clientaccesspolicy.xml” file and the “crossdomain.xml” file.
- Using a crossdomain.xml file to allow cross-domain access
- Using a clientaccesspolicy.xml file to allow cross-domain access
- Using a Web Developer Helper Tool
First, we are going to create a Web Service using Visual Studio. Then we will create a Silverlight Application in a different Visual Studio instance. In this Silverlight application, we will reference the Web Service and use the method exposed by this Web Service. We will see how to use the “crossdomain.xml" and “clientaccesspolicy.xml” files so that we can make the call to Web Service methods from the Silverlight Application.
Step 1: Create a Web Service using Visual Studio
Open Microsoft Visual Studio 2010 -> File -> New Website -> under installed Templates select “Visual C#’ -> Select ASP.NET Empty Website and name it as “
MyWebApplication“ as shown below:
Step 2: Open Solution Explorer (View -> Solution Explorer). Right click on the “
MyWebApplication” in bold and click on “Add New Item” -> Select Web Service(Scroll down to see Web Service) and rename it as MyWebService.asmx” as shown below. Then click on Add.
Once a Web Service is added to the application, open the “MyWebService.asmx.cs” file and you will find that this Web Service exposes the “
HelloWorld” method which can be invoked by the Silverlight client application. Now build the Web Service and press Ctrl+F5 to run the application. For simplicity, I am not adding any other method but using the existing “
This opens the browser window with the webservice as shown above. As we can see, the “
webservice exposes the
HelloWorld method. Copy the Web Service URL from the browser.
This is the webservice URL which contains the following things:
- Protocol to be used to access the webservice (http).
- The Server on which the
webservice is hosted. Since we have developed the web service on local machine using the Visual Studio development server, it is hosted on localhost on port number:1133. It can be any server name/port number on which your
webservice is hosted. The web service “MyWebService.asmx”. Web services have the extension “.asmx”.
- We are going to use this
webservice URL in our Silverlight application.
Step 3: Now create a Silverlight Application.
Open a new instance of Visual Studio -> File -> New Project -> Below Installed Templates -> select Visual C#-> Silverlight -> Silverlight Application -> Rename it to “
MySilverlightApplication” as shown below and then click on ok button.
This creates a “
MySilverlightApplication” Silverlight application. Let us add a web service reference: Open Solution Explorer (View -> Solution Explorer) -> Right click on “
MySilverlightApplication” -> click on.
Add Service Reference-> This opens Add Service Reference window for Address paste the web service url we have copied earlier http://localhost:1133/MyWebService.asmx -> Go. This discovers the web service and adds it to Services column. Now click on ok. This Adds the web service to the project and generates the proxy class so that we can access the web service methods from the Silverlight Application. In the Service References folder, you will find the “
MyServiceReference” file which is the
webservice we have added reference to. It also generates the “
ServiceReferences.ClientConfig” file which contains details about the web service such as the Web service location (address), binding and other details. You can explore
MyServiceReference file in the “Service References” folder by right-clicking “
MyServiceReference “ and selecting View in Object Browser. Note that it contains the
MySilverlightApplication.MyServiceReference.MyWebServiceSoapClient class and its methods. These are methods invoked to call the service.
Note: Make sure that the Web Service is running if it is developed using Visual Studio development server.
Step 4: Invoking the
webservice method from the Silverlight Application by constructing a proxy to the service.
TextBlock to the MainPage.xaml file as shown below:
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock Height="23" HorizontalAlignment="Left" Margin="10,10,0,0"
Name="textBlock1" Text="TextBlock" VerticalAlignment="Top" />
Go to the MainPage.xaml.cs (code-behind) file in the client application and add the following
using statements at the top of the page.
You must instantiate the Web service proxy before using the service:
public partial class MainPage : UserControl
MyWebServiceSoapClient proxy = new MyWebServiceSoapClient();
void proxy_HelloWorldCompleted(object sender, HelloWorldCompletedEventArgs e)
if (e.Error == null)
textBlock1.Text = e.Result.ToString();
textBlock1.Text = "Error getting the result";
Points to be observed here are:
- All Web service calls in Silverlight are asynchronous.
- The web service proxy contains two members for each operation in the service: an asynchronous method and a completed event. For example, consider the “
HelloWorld” service operation. We first add an
HelloWorldCompleted within the scope of the
MainPage() constructor. This is the event that will be invoked when the service returns the data we requested. After the event is set up, we are ready to make the call to the service by calling
HelloWorldAsync method. The above sample shows the code for these two steps.
- Visual Studio makes it easy to write asynchronous code. Simply type
proxy.HelloWorldCompleted += and press the TAB key twice. The event handler and the event handler method will automatically be created.
- The event handler specifies that the
proxy_HelloWorldCompleted method should be called when the service returns some data.
- We need to handle errors robustly in the “
proxy_HelloWorldCompleted” method. To handle error conditions, we must detect the error by checking the
Error property on the resulting event arguments, before accessing the
Result property. If you try to access the
Result property when an error condition has occurred, an exception will be thrown. The above example shows how to make the event handler robust against errors.
- The error can be due to several reasons such as: the service may not be available, or the service address may be wrong or the errors may also occur due to cross-domain access issues.
Step 5: Now Press Ctrl+F5 and run the project. Oops. The application gives an error. To see where exactly the error is, I have used the “web developer helper” tool. This tool is a free browser extension for Internet Explorer that provides a set of tools and utilities for the Web developer, Ajax and ASP.NET developers. The tool provides features such as a DOM inspector, an HTTP tracing tool, and script diagnostics and immediate window.
You can download and install the “web developer helper “ tool from “http://projects.nikhilk.net/WebDevHelper” website.
To open Web Development Helper tool on the IE window -> Right side go to Tools->Explorer Bars -> click web developer helper. Now refresh the page and check the “Enable Logging” checkbox and you will see that Silverlight first looks for Silverlight’s policy definition file: “clientaccesspolicy.xml”. If it can’t find it, it searches for “crossdomain.xml” file. In our case, it is unable to find both the files as it returns the Status code as “404”.
This means that we have to add these files to be able to make service requests to the
webservice. It is the responsibility of
webservice author to put on server the Cross domain policy file to enable cross domain access of their service from an application.
Step 6: Now add an “xml” file to the webservice “
MyWebApplication” with the following content and name it as clientaccesspolicy.xml that allows access to the service. The following configuration allows access from any other domain to all resources on the current domain.
<resource include-subpaths="true" path="/"></resource>
Alternatively, if you want to allow access from only one other domain, such as http://microsoft.com, replace the
<domain uri="*"/> line within the
<allow-from> element of the clientaccesspolicy.xml file above with the line
To allow access to an HTTPS service from any Silverlight control hosted over HTTP application, you need to put the
<domain uri=”http://*” /> element inside your
<allow-from> element. access domain.
Note: Make sure that these 2 files:"crossdomain.xml” and “clientaccesspolicy.xml” are located in the root of the web service application.
You can also add the “crossdomain.xml” file by adding an XML file with the following configuration:
<!DOCTYPE cross-domain-policy SYSTEM
<allow-http-request-headers-from domain="*" headers="SOAPAction,Content-Type"/>
Step 7: Now run the Silverlight Application (Ctrl + F5). It executes successfully and you can see in the “Web Developer Tool” that the call to the policy files returns no error as the status code is 200.
Some of the real time examples of the crossdomain policy files in use are listed below:
Go to http://www.amazon.com/crossdomain.xml you will find the below file. It does not allow public access but enables access from different websites.
Another example is flickr website. It gives cross domain access different from their site. That is from api.flickr.com/crossdomain.xml.
It enables API access using some controllable mechanism keeping service on different domain than content domain. This is one of the best practices to be used when using the crossdomain file.
Below are some of the Best Practices for cross-domain access:
When exposing a service for cross-domain accesses, observe the following precautions:
In cross-domain-enabled services, rely only on message body to authenticate the caller.
For example, suppose a cross-domain-enabled photo sharing service that requires user authentication is accessed using http://api.picasa.com/PhotoService/GetPhotoalbum. The service should not rely on cookies to authenticate the user. However, an authentication scheme could be used where a user authentication token is passed as part of the message or the URL - for example, http://api.picasa.com/PhotoService/GetPhotoalbum?userToken=ABCOLK.
Separate your cross-domain-enabled services from your regular Web pages and non-cross-domain-enabled services. It is best to do this separation by domain or sub-domain, when using the Silverlight policy file: the clientaccesspolicy.xml file. It is possible to do the separation by URL space.
For example, http://flickr.com is a Web site with Web pages that use cross-domain authentication mechanisms that are unsafe, such as cookies. To add services that are safe for cross-domain access, add them to a separate sub-domain like http://api.flickr.com. Then http://flickr.com/clientaccesspolicy.xml should not exist, but http://api.flickr.com/clientaccesspolicy.xml should exist and should enable cross-domain access.
- 2nd October, 2011: Initial version
I am a Software Developer in Dotnet technologies. I also provide online training in dotnet technologies.