Consuming External Web Services from Silverlight Application

Accessing web services from Silverlight.


While exploring Map api integration with SOI application, I felt that a separate article on consuming external web services from a SL application is worth writng. As we know, services can be SOAP based (WCF bases) or can be REST (Simple HTTP) based on their implementation. As you goggle you will find many services from different providers; here you can find some of them (webservice directory). Some might be useful; saving lots of time and some may look fancy.

Silverlight can access some services directly for e.g HTTP/REST type and some using proxy for e.g. SOAP. Well before describing the process let's have a look at a web service in Silverlight. Services hosted by various host come with various security policies for e.g yahoo allows access to it's services for authenticated requests only and authentication can be achieved by using OpenID, Oauth and Hybrid (Yahoo API Auth.); similarly Google services. These external service administrators create policy files to restrict the request from other domains without proper authentication.

Basics of Webservice

This article assumes that readers will have a basic understanding of webservices; I suggest referring to the tutorials from W3C to refresh the concept (W3C Webservices concept).

Cross Domain Policy for services
  
What is Cross Domain Access

Suppose Domain A is hosting a webservice. Request made from Domain B to the service at A is said to be Cross Domain access.

By default the Silverlight allows access to the services hosted at same domain with out any restriction but if it's external then, that service should allow your domain specifically. Generally the service providers uses crossDomain policy files to grant/restrict the request. On the same line if you are going to build your own service and want to be accessed from other domain then you have to add clientaccesspolicy.xml, where either you can allow all external requests or else specific domains.

The typical structure of a clientaccesspolicy.xml can be as bellow, here it allows access to all:

<;?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>


As mentioned above some of the services such as for images and news feed are open for all, such as from Geonames. You can find more details about these apis here.

External RESTful Service from Silverlight
  
As we know the Silverlight client sitting inside a browser has restricted access to the server. For accessing database too it depends on proxy service calls through WCF. All the service calls from Silverlight is asynchronous by their behaviour, as contrary to synchronous call of ASP.Net. Well choosing Rest services here for this article can be seen as to maintain the simplicity and as most of the providers support it. Rest services expose themselves through HTTP, using their url. On a request made to the service it can return results in various formats for e.g XML, JSON etc.

An external service from Silverlight can be called 2 ways

  • Either ask the service provider/administrator to allow your domain to access the service, by adding your domain to their policy files
  • Using a proxy service call from your domain to that external webservice and your Silverlight app request to your domain proxy .

Now, for example I have chosen a service from GeoName which allows me to get geographic details as results. As mentioned their web. This a free service and allows all domain access. Their service url says:

Url    >>      api.geonames.org/postalCodeSearch?&username=***

Result   >>      returns a list of postal codes and places for the placename/postalcode query as xml document

With your username and the search argument the url will be â€":http://api.geonames.org/search?q=orissa&username=********

Now from your Silverlight code we can call the service using WebClient or HTTPWebRequest. The code for accessing a webservice can be:

  1. string path = @"http://api.geonames.org/search?q=orissa&username=********";
  2. public MainPage()
  3. {
  4. InitializeComponent();
  5. }
  6. private void btnCallService_Click(object sender, RoutedEventArgs e)
  7. {
  8. WebClient client = new WebClient();
  9. client.DownloadStringCompleted += (s, ev) =>
  10. {
  11. MessageBox.Show(ev.Result);
  12. };
  13. client.DownloadStringAsync(new Uri(path));
  14. }

  • Create a Webclient for sending a HTTP request to server.
  1. WebClient client = new WebClient();

  • Assign the callback with the async operation completed event handler.
  1. client.DownloadStringCompleted += (s, ev) =>

    • Call DownloadStringAsync with service URL
    1. client.DownloadStringAsync(new Uri(path));


    Here in the above example we are showing the result in a message box after calling the service; instead of which we can parse the xml and get the meaningful data source for our app.
     

    SNAGHTMLd026e5

    The XML data can be parsed either using  XmlReaderLinq To XMl or using XmlSerializer which converts the XML data to plain CLR objects. The parsing of XML will not be an issue with XMLReader. I will cover the conversion of XML data to a CLR object using XMLSerializer with an example in my next article.

    Conclusion
    M
    ost of the services do not allow access as simple as mentioned above. A Yahoo API invites some extra steps and some more code stuff. You may refer to this article for accessing a Yahoo web service from ASP.Net. Use of a 3rd party proxy service also provides another way; for e.g Yahoo Pipes. But it's always a nice feeling to use programs available free without writing anything Smile. Ok. I will try to extend the article with accessing services other than REST. Until then keep learning.

    Link and Source Code

    GeoSearch Live Link – : GeoSearch

    Download SourceCode -: GeoSearch