HTTP Compression for your Silverlight ADO.NET DataServices

by Vladimir Enchev | Comments 13

I’m happy to announce that with Q1 2009 release of RadControls for ASP.NET AJAX (Telerik.Web.UI) you will be able to compress the response from ADO.NET DataServices (formerly "Project Astoria") in Silverlight web applications with simple web.config registration:

web.config

<
httpModules>
  <addname="RadCompression" type="Telerik.Web.UI.RadCompression" />
</
httpModules>

Here is the result for Northwind Customers with ATOM and JSON response type:

Untitled

ATOM : Bytes Received: 11,623 (uncompressed 92,848)
JSON  : Bytes Received:   9,237 (uncompressed 39,460)

I’ve made small Silverlight application to illustrate the new feature – two instances of RadGridView bound to Northwind Customers using ADO.NET DataService:
Untitled1

The first grid is bound using the traditional Silverlight ADO.NET DataService approach with DataServiceContext:

private void BeginATOMRequest()
{
    DataServiceContext context = new DataServiceContext(new Uri("WebDataService1.svc", UriKind.Relative));
    DataServiceQuery<Customers> query = context.CreateQuery<Customers>("Customers");
    query.BeginExecute(ATOMRequestCompleted, query);
}

private void ATOMRequestCompleted(IAsyncResult asyncResult)
{
    DataServiceQuery<Customers> query = asyncResult.AsyncState as DataServiceQuery<Customers>;
    RadGridView1.ItemsSource = query.EndExecute(asyncResult).ToList();
}


and the second grid is bound using pure asynchronous WebRequest with JSON response:

private void BeginJSONRequest()
{
    Uri documentUri = HtmlPage.Document.DocumentUri;
    Uri uri = new Uri(String.Format("{0}://{1}:{2}/{3}", documentUri.Scheme, documentUri.Host, documentUri.Port, "WebDataService1.svc/Customers"), UriKind.Absolute);

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = "GET";
    request.Accept = "application/json";
    IAsyncResult result = request.BeginGetResponse(new AsyncCallback(JSONRequestCompleted), request);
}

private void JSONRequestCompleted(IAsyncResult result)
{
    HttpWebRequest request = (HttpWebRequest)result.AsyncState;
    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);

    List<Customers> list = new List<Customers>();

    using (Stream stream = (Stream)response.GetResponseStream())
    {
        JsonValue items = JsonArray.Load(stream);

        foreach (KeyValuePair<string, JsonValue> item in items)
        {
            if (item.Key == "d")
            {
                JsonArray array = (JsonArray)item.Value;

                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Customers));

                foreach (JsonObject child in array)
                {
                    using (MemoryStream jsonStream = new MemoryStream(Encoding.Unicode.GetBytes(child.ToString())))
                    {
                        Customers customer = (Customers)serializer.ReadObject(jsonStream);
                        list.Add(customer);
                    }
                }
            }
        }
    }

    Dispatcher.BeginInvoke(() =>
    {
        RadGridView2.ItemsSource = list;
    });
}

Enjoy!

[Download]

,
Senior Technical Architect

13 Comments

Ben Hayat
A great step to the future;
Vlad, a few questions (my first impressions before looking at the code yet):
a) Does the client query become compressed too?
b) With this feature, is this an automatic feature as part of a framework that can be turned ON or OFF, or is this something that developer needs to compress the data before it leaves the server and then uncompress it when it gets to client. I had seen this feature somewhere else, but it's was developer's responsibility to do so, V.S. part of the framework.
c) While you're at it, would it be possible to encrypt the data for security reason, so if someone intercepts it, they would not be able to see the real data?
d) Could Silverlight application use JSON or ATOM without any changes to the logic of the code?
e) Will the Compression routine be just another DLL that gets added to project or is it part of Microsoft compression system, or do have to license it?
f) Why doesn't Astoria build this feature into it's delivery system? or make the data binary than text to begin with?
Thanks!
..Ben
Vlad
Hi Ben, Straight onto your questions: a) Generally the request size is very small (less than 1K) and you do not need to compress this. b) The feature can be enabled with simple HttpModule registration in the Silverlight web application web.config file. c) The problem with the encryption in Silverlight is where do you keep the key. This cannot be .xap file since everyone will be able to find this key. d) My demo application is such example - finally you will get List<Customers>. e) The compression module is part of RadControls for ASP.NET AJAX (Telerik.Web.UI.dll). You need to add this dll in the bin folder of the Silverlight web application. f) Unfortunately I have no idea. Vlad
Ben
Thanks Vlad; what's the size of Telerik.Web.UI.Dll? Would that compression ever become of part of the SL namespace, so we would not need to load the ASP module in?

Thanks again!
..Ben
Todd
@Ben- I think the idea here is that the data will be compressed on the server, not directly in the Silverlight application. So, this assumes that you're hosting your Silverlight application in a ASPX page and that you've configured your ASP.NET web site to use the HttpModule mentioned. Since Modules are invovled with -every- request in the ASP.NET pipeline, this module will automatically compress any JSON or ATOM data before it's sent to your Silverlight client when calling a local web service (thus reducing the bytes that must be sent over the wire).

That means the size of the Telerik.Web.UI DLL is irrelevant since it lives on the server. And to get this benefit, you need the compression to happen on the server before the data reaches the SL client, so I don' think there is much value in moving the compression to the SL namespace.

Does that help?
Ben
Mr. Todd, great post and answer. The picture is much more clear now, as far as what, where and when things happen. Thanks for clearing up.
So, on the client side, whose responsibility will it be to uncompresse the coming data? Will it be the SL client? Half of my question was related to compressing the data (which you clearly explained and I have no problem with that), but to uncompress it, do we need to include the above mentioned DLL? That's my concern to limit the size of the XAP.
Do you remember, you and I had a conversation in Orlando in TechEd, when I said, in SL case, smaller is better, and you smiled? I'm still striving to get smaller ;-)
Valio
Hi Ben,

the decompresion is done by the browser itself, you don't need anything in Silverlight - you just got that for free.

Check the code and see the "JSONRequestCompleted" method for more info.

--
Valio
Ben
>>the decompresion is done by the browser itself, you don't need anything in Silverlight - you just got that for free<<
That's awesome man!
>>Check the code and see the "JSONRequestCompleted" method for more info.<<
Ok,ok! Don't yell at me, I will ;-)
What are you doing up so late, go to sleep...
Jaime Bula
This is AWESOME.

Is there a way to meke it work with WCF endpoints?
Alex
Hi Vald great code.
how about zipping the client also?
I know you said the requestes are small but that is not true, at least not tru if you have enable CRUD on you dataservice and you want to send batchs of commands, in this scenario being able to also zip the request on the client side and then unzip it on the server side before ado.net process it is very useful, any ideas of how this can be done?
TIA
Jesper
How about using this with a RIA dataservice ?
Jesper
How about using this with a RIA dataservice ?
Vlad
Hi Jesper,

Native support for RIA services is already added and will be available in our next latest internal build.

Vlad
Rodney
Would this speed up a large WCF call? I am transferring > 50 megs of data - is this worth investigating?

Comments

  1.    
      
      
       
  2. (optional, emails won't be shown on public pages)
  3. (optional)
Read more articles by Vladimir Enchev - or - read latest articles in Developer Tools


Follow vladimir_enchev on Twitter