- Google Message-Handling Basics
- Silverlight Message-Handling Basics
- Handling the HTTP Methods
- HTTP DELETE
- Ready for Our Closeup!
Silverlight Message-Handling Basics
Unlike GAE, Silverlight only allows you to execute two of the basic HTTP verbs: GET and POST. That rule may sound awfully restrictive, but there are ways around this limitation, such as using JavaScript to do things that Silverlight won't let you do. XMLHttpRequest is a JavaScript object that exists in most web browser environments, and it understands how to send DELETE, PUT, and HEAD as well as GET and POST. Silverlight objects can call JavaScript in the browser this way:
HtmlPage.Window.Invoke(string methodName, params object[] args)
When a URL understands the HTTP GET and POST methods, you use this:
WebRequest.Create(Uri destination)
WebRequest.Create returns a WebRequest object with the following properties available:
- Method: Set this string to the value of the HTTP method to invoke. In Silverlight 2.0, that method is either GET or POST.
- ContentType: Set the type of content (if any) that's being sent. If you GET a resource from a URI, leave this setting alone. If you POST data, set this to the recognized MIME type in the request body.
- Headers: You can add HTTP headers to the request.
We'll go over sending and receiving messages shortly. We'll also walk through how each part of the choreography is accomplished for the four common HTTP methods, starting at the request and traveling all the way through to reading the response.
But first, there's one little thing we need to handle: authentication.
Application Startup
When the user first arrives at the application, she needs to authenticate, as shown in Figure 1. Once the user logs in, she sees a bit more, as shown in Figure 2.

Figure 1 To use our sample Silverlight-Google App Engine application, the user needs to sign in.

Figure 2 The user interface of our sample application.
The Silverlight control lives within the red outline I added to Figure 2. I put it into that page with the following markup:
<object width="100%" height="100%" data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="Xaml1"> <param name="source" value="/PhotoWebSL.xap" /> <param name="minRuntimeVersion" value="2.0.31005.0" /> <param name="autoUpgrade" value="true" /> <param name="EnableHtmlAccess" value="true" /> <!-- Display installation image. --> <a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;"> <img src="https://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/> </a> </object>
The Python application remembers the current user by passing a cookie back to the browser after authentication. This cookie is then sent with every request from the browser, including requests that originate from the Silverlight control. The Python backend uses this cookie to determine user identity on each HTTP request.
When the Silverlight control loads, it initializes three URIs with which it communicates:
- The URI from which it will get lists of images
- The URI to use when updating or deleting image data
- The URI to use when adding new images to the application
- The base URI for any images that will be loaded
The control fetches the images for the logged-in user. The following lines do the work:
Uri ImageService { get; set; } Uri ImageUploadService { get; set; } Uri ImageListService { get; set; } public Page() { InitializeComponent(); ImageService = new Uri(App.Current.Host.Source, "/img"); ImageListService = new Uri(App.Current.Host.Source, "/images"); ImageUploadService = new Uri(App.Current.Host.Source, "/"); ImageItem.BaseUri = ImageService.ToString(); Loaded += (s, e) => { LoadImages(); }; }
The lines to set URIs (shown in bold) might look a bit odd. This particular constructor of Uri joins the scheme, server, and port information from the first argument and appends the string in the second argument. In our case, App.Current.Host.Source is as follows:
http://sseely-silverlight.appspot.com/PhotoWebSL.xap
After running this code for the example, we get the results shown in the following table:
Class |
Handles This URL |
ImageService |
http://sseely-silverlight.appspot.com/img |
ImageListService |
http://sseely-silverlight.appspot.com/images |
ImageUploadService |
http://sseely-silverlight.appspot.com/ |
If you deploy to a different GAE application, the roots are different.