Overcoming Cross-Domain Issues in Silverlight

by kevin 5/2/2008 9:24:00 AM

One of the easiest ways to deal with cross-domain issues in Silverlight is to write a WCF service that acts as a proxy for the calls you want to make. For example, in my Twitter control, I want to be able to load XML from the RESTful Twitter service at the following address:

http://twitter.com/statuses/user_timeline/wkh.xml

However, when invoking the RESTful Twitter service from a WebClient in Silverlight, I get the dreaded "Download Failure" error when I call DownloadStringAsync. This is because the Twitter.com site doesn't have an entry in its clientaccesspolicy.xml file for my test domain. And that's never going to happen, right? To solve this problem, consider exposing a WCF service from the site from which the Silverlight control emanated. The WebClient class can be used on the server side without the same cross-domain control being applied by Twitter.com. For the example outlined above, I called my service TwitterProxy. The ITwitterProxy couldn't be simpler:

using System.ServiceModel;

[ServiceContract( Namespace = "urn:gotnet:biz:Services:2008:05" )]
public interface ITwitterProxy
{
    [OperationContract]
    string GetUserTimeline( string user, int count );
}

The service implementation is also quite simple. It uses the WebClient just as I would from Silverlight (if I could):

using System;
using System.Net;

public class TwitterProxy : ITwitterProxy
{
    public string GetUserTimeline(string user, int count)
    {
        user = (user != null) ? user.Trim() : String.Empty;
        count = (count < 1) ? 1 : (count > 20) ? 20 : count;
        WebClient client = new WebClient();
        Uri uri = new Uri( String.Format("http://twitter.com/statuses" +
            "/user_timeline/{0}.xml?count={1}", user, count ) );
        return client.DownloadString(uri);
    }
}

Expose an SVC file on the server to host the new service. In this example, the URL to invoke the new service is:

http://localhost/WebSite/TwitterProxy.svc

So, to invoke this service from Silverlight, add a proxy to the Silverlight control, using the service address and invoke it like this:

private void OnLayoutRootLoaded(object sender, RoutedEventArgs e)
{
    TwitterProxyClient client = new TwitterProxyClient(
        new BasicHttpBinding(), new EndpointAddress(
        "http://localhost/Website/TwitterProxy.svc"));
    client.GetUserTimelineCompleted += OnGetUserTimelineCompleted;
    client.GetUserTimelineAsync("wkh", 10);
}

void OnGetUserTimelineCompleted(object sender,
    GetUserTimelineCompletedEventArgs e)
{
    // open a Twitter Status dialog, passing the XML string
    NavigationHelper.Navigate(new FadeTransition(
        TimeSpan.FromMilliseconds(750.0d)), new Status(e.Result));
}

The dreaded "Download failure" error is gone. Nice. of course, the potentially bad side effect of this technique is that all of the Twitter service traffic will be flowing through the server that's hosting the TwitterProxy. Think about that before using this technique.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Architecture | Silverlight | WCF

Powered by BlogEngine.NET 1.3.1.0
Theme by Mads Kristensen


Kevin's on Twitter / FriendFeed

W. Kevin Hazzard Welcome to Kevin Hazzard's Blog. Kevin is a Software Architect, Professor and Microsoft MVP specializing in C#, WCF, Silverlight and IronPython.

View Kevin Hazzard's profile on LinkedIn
Microsoft MVP Award Join me at CodeStock

Calendar

<<  May 2008  >>
MoTuWeThFrSaSu
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

View posts in large calendar

Recent posts

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Sign in