Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable gzip compression in Simple OData Client?

I'm trying to perform a query that retrieves information from a CRM Dynamics with the Simple OData Client library like this (C#):

var settings = new ODataClientSettings(resource + "/api/data/v8.0/");
settings.BeforeRequest = (request) =>
    {
        request.Headers.Clear();
        request.Headers.Add("Authorization", accesstoken.AccessTokenType + " " + accesstoken.AccessToken);
    };

settings.PayloadFormat = ODataPayloadFormat.Json;
var client = new ODataClient(settings);
var annotations = new ODataFeedAnnotations();

var transactions = await client.For("mss_transaccions").FindEntriesAsync(annotations);
while (annotations.NextPageLink != null)
{
    transactions = transactions.Union(await client.For("mss_transaccions").FindEntriesAsync(annotations.NextPageLink, annotations));
}

While this works, it is extremely slow because my query on the mss_transaccions table has 7200 entities. I'm looking at the output in Fiddler and I can see that it is trying to download about 20 MB of information.

I tried to run the same query on Google Chrome, and I could see that by default the obtained response is compressed in gzip format, going from 20MB to some mere 500KB. So I'm deducing that Simple OData Client is not doing any kind of compression, and that's why it is so tremendously slow.

In addition, the request from OData Simple Client asks for metadata information, which adds another 4MB, while Chrome or a simple HttpClient request do not need to make that call.

Is there anything I can do to improve that and enable compression?

Thank you.

like image 777
David Jiménez Martínez Avatar asked Apr 25 '16 12:04

David Jiménez Martínez


3 Answers

In your BeforeRequest action, add the Accept-Encoding header as follows:

settings.BeforeRequest = (request) =>
{
    // ... other headers as above
    request.Headers.Add("Accept-Encoding", "gzip");
};
like image 155
lencharest Avatar answered Sep 25 '22 13:09

lencharest


I've been able to finally enable compression and speed up the overall process. The whole discussion can be found here: https://github.com/object/Simple.OData.Client/issues/238

To lay it down simply and quickly, you just need to modify the message handler in the ODataSettings instance with the following piece of code:

settings.OnApplyClientHandler = handler =>
            {
                handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
            };

Now the httpRequests are sent as gzip,deflate and decompressed on response properly.

like image 38
David Jiménez Martínez Avatar answered Sep 26 '22 13:09

David Jiménez Martínez


If you inspect which headers is sending Chrome and try to replicate them in C#?

Also, If I have to access CRM from C#, I would use the Microsoft.Xrm.Sdk as opposed to OData. You have loads of proxy types and requests that will allow you to write code much more cleaner. OData has other limitations which QueryExpressions / CRM LINQ / FetchXml don't have too.

OData would make more sense for JS code (i.e. requests from a CRM form).

like image 28
Jordi Avatar answered Sep 24 '22 13:09

Jordi