Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Access a Web Service from a Silverlight Application

0.00/5 (No votes)
2 Oct 2011 2  
This article discusses how to access a Web Service from a Silverlight Application. It has sample code attached.

Introduction

In this article, we are going to see how we can access a Web Service from a Silverlight application.

Topics Covered

  1. Making a Service available across domain boundaries
  2. Significance and best practices of the “clientaccesspolicy.xml” file and the “crossdomain.xml” file.
  3. Using a crossdomain.xml file to allow cross-domain access
  4. Using a clientaccesspolicy.xml file to allow cross-domain access
  5. 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:

image001.jpg

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.

image002.jpg

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 “HelloWorld” method.

image003.jpg

This opens the browser window with the webservice as shown above. As we can see, the “MyWebServicewebservice exposes the HelloWorld method. Copy the Web Service URL from the browser.

”http://localhost:1133/MyWebService.asmx”

This is the webservice URL which contains the following things:

  1. Protocol to be used to access the webservice (http).
  2. 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”.
  3. 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.

image004.jpg

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.

image005.jpg

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.

image006.jpg

Step 4: Invoking the webservice method from the Silverlight Application by constructing a proxy to the service.

Add a 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" />
    </Grid>

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.

using MySilverlightApplication.MyServiceReference;

You must instantiate the Web service proxy before using the service:

public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            //instantiate the Web service proxy 
            MyWebServiceSoapClient proxy = new MyWebServiceSoapClient();
          
            //Invoke the "HelloWorldCompleted" method when the 
            //"HelloWorld" method is executed and returns.
            proxy.HelloWorldCompleted += 
	     new EventHandler<HelloWorldCompletedEventArgs>(proxy_HelloWorldCompleted);
            //Call the "HelloWorld" method.
            proxy.HelloWorldAsync();
        }
        //Invoked when the "HelloWorld" method is executed and returns
        void proxy_HelloWorldCompleted(object sender, HelloWorldCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                textBlock1.Text = e.Result.ToString();
            }
            else
            {
                textBlock1.Text = "Error getting the result";
            }
        }
    }

Points to be observed here are:

  1. All Web service calls in Silverlight are asynchronous.
  2. 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 EventHandler to 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.
  3. 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.
  4. The event handler specifies that the proxy_HelloWorldCompleted method should be called when the service returns some data.
  5. 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.
  6. 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”.

image007.jpg

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.

<?xml version="1.0" encoding="utf-8" ? >
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from>
        <domain url="*"></domain>
      </allow-from>
      <grant-to>
        <resource include-subpaths="true" path="/"></resource>
      </grant-to>
    </policy>
  </cross-domain-access>
  
</access-policy>

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 <domain uri="http://microsoft.com"/>.

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:

<?xml version="1.0" encoding="utf-8" ?>
<!-- The file must be configured to allow access to the service from any other domain, 
or it is not recognized by Silverlight 4.
Save the crossdomain.xml file to the root of the domain where the service is hosted. 
If, for example, the service is hosted in http://fabrikam.com, 
then the file must be located at http://fabrikam.com/crossdomain.xml.
-->
<!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="SOAPAction,Content-Type"/>
</cross-domain-policy>

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.

image008.jpg

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.

image009.jpg

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.

Reference

History

  • 2nd October, 2011: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here