There has been a fair amount of feedback regarding the HttpWebRequest type in Silverlight. People have asked or commented about:
The response to most of this feedback has been that we are limited by what functionality the browser provides to plugins. For example, the API implemented by all browsers but IE (called the NPAPI, short for Netscape Plugin API) basically has the following support for networking:
You may be wondering why we were able to support synchronous requests in Silverlight 1.1 alpha, why it did support headers in GET requests, etc. In Silverlight 1.1 alpha we didn't use the aforementioned APIs. Instead, we essentially wrapped the browser's XMLHttpRequest object that you can use in JavaScript today via our HTML/JS bridge. This had a few disadvantages:
There were a few things we could've done (and could still do) to deal with this. We could've used the operating system's networking stack and address most of the feedback we've had so far. The main disadvantage would be that all the requests would execute in their own security context. This means that if a user is authenticated using Windows authentication, any request sent by the Silverlight application would still be unauthenticated. Alternatively we could've created a hybrid, and choose what request type we would use based on the functionality you need. For example, if you don't care about binary data but you do care about headers in GET requests, we could use the browser's XMLHttpRequest object. But if you care about binary data and need authentication, we could use the browser's plugin API. Needless to say this would allow for a rather awkward/inconsistent programming experience.
Until we find a better way to deal with all of these problems in a future release, you will unfortunately have to deal with these shortcomings. To help you out a little though, I've put together some code that basically does create some sort of hybrid between XMLHttpRequest and the current version of HttpWebRequest in Silverlight. In a nutshell, you can write code like this:
| C#: |
1 2 3 4 5 6 7 8 9 10 11 |
// Based on the request uri, this will either return the Silverlight HttpWebRequest // type (which supports binary data and cross-domain requests), or a HttpWebRequestEx // type (which supports PUT/HEAD/etc, headers and synchronous requests). var request = HttpWebRequestEx.Create(requestUri); // Assume we are requesting a resource on our server. Cast to HttpWebRequestEx // such that we can call GetResponse for a synchronous request. var sameDomainRequest = (HttpWebRequestEx)request; sameDomainRequest.Headers["foo"] = "bar"; var response = sameDomainRequest.GetResponse(); // ... |
I've also put together a type which might make it a little easier to work with HTTP requests. It's basically a wrapper around HttpWebRequestEx and HttpWebRequest and it is implemented as a fluent interface which should make it a little easier to construct a request:
| C#: |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Synchronous request. var response = Request.To("foo.txt").Send().ReadAllText(); HtmlPage.Window.Alert(response); // Asynchronous request with a header and POST data. Request.To("foo.txt") .WithMethod("POST") .WithHeader("foo", "bar") .WithBody(writer => writer.Write("hello")) .SendAsync(response => HtmlPage.Window.Alert(response.ReadAllText())); // Asynchronous, cross-domain request. Request.To("http://services.digg.com/stories/topic/microsoft?count=3&appkey=http%3A%2F%2Fexample.com%2fapplication") .SendAsync(response => HtmlPage.Window.Alert(response.ReadAllText())); |
You can download the sources and binaries to try this out yourself. Let me know what you think.
No comments yet.
You must be logged in to add your own comment.