OData Compression in Windows Phone 7.5 (Mango)
One of the most frequently requested features for OData is payload compression. We have added two events to DataServiceContext in the OData phone client included in the Windows Phone SDK 7.1 that enables you to work with compressed payloads:
- WritingRequest – occurs immediately before a request is sent
- ReadingResponse – occurs immediately after a response is received
Now, let’s take a look at these in action. Here is a method that adds support for gzip compression for OData feeds in a Windows Phone app:
using SharpCompress.Compressor;
using SharpCompress.Compressor.Deflate;
private void EnableGZipResponses(DataServiceContext ctx)
{
ctx.WritingRequest += new EventHandler<ReadingWritingHttpMessageEventArgs>(
(_, args) =>
{
args.Headers["Accept-Encoding"] = "gzip";
}
};
ctx.ReadingResponse += new EventHandler<ReadingWritingHttpMessageEventArgs>(
(_, args) =>
{
if (args.Headers.ContainsKey("Content-Encoding") &&
args.Headers["Content-Encoding"].Contains("gzip"))
{
args.Content = new GZipStream(args.Content, CompressionMode.Decompress);
}
}
);
}
This method registers two event handlers that make all of the client-side modifications to the message necessary to accept gzip compressed messages; just pass in your DataServiceContext. We’ll examine each event handler individually.
The WritingRequest event handler
Here we simply set the Accept-Encoding to gzip to inform the server that we can accept a gzip’d response. With this header set, the server will send us a gzip’d response, if it can.
The ReadingResponse event handler
The Content-Encoding header tells us how the server encoded the response body. We only modify the response body (in args.Content) when this header has been set to gzip. In this way, gzip-compressed content is decompressed with GZipStream, and everything else is just left as is.
Unfortunately, GZipStream is not currently supported on Windows Phone. We must rely on a third-party library to perform decompression and so we have used the SharpCompress Library, which worked quite well. If you download SharpCompress, you’ll get a zipped folder containing some libraries. Just add SharpCompress.WP7.dll to your project references, and you’ll be ready to use GZipStream on Windows Phone. If you’ve never added a reference before, check out this walkthrough. You can probably skip straight to the section called “To add a reference in Visual C#”. Browse to where you saved the SharpCompress.WP7.dll, and then add it to your project.
Note that if we also wanted to send a compressed request (POST) to the data service, we could simply set the Content-Encoding header to gzip in the WritingRequest handler and compress the payload stream returned by the Content property.
Server-Side Configuration
The client side changes we’ve discussed so far require that our server be configured to support message compression. If you are using IIS, check out these links to get compression set up: IIS 6.0, IIS 7.0, or a more extensive guide for both. You should be compressing OData payloads as soon as your server is ready.
Evan Czaplicki & Shayne Burgess
OData Team
Comments
Anonymous
November 29, 2011
Any chance we'll get this as part of the Silverlight Client? Currently there's no way to enable compression for those of us who use the ClientStack, especially for OOB scenarios.Anonymous
August 08, 2013
I created a context classes by referencing OData Web Service in VS2013, but WritingRequest event is not firing during request. ReadingResponse is firing though. It's a WP8 project. Any guesses?