2016-04-25 14 views
5

Próbuję wykonać kwerendy, która pobiera informacje od A Dynamics CRM z Simple OData biblioteki Client tak (C#):Jak włączyć kompresję gzip w prostym kliencie OData?

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)); 
} 

Chociaż to działa, to jest bardzo powolny, ponieważ moje zapytanie na mss_transaccions tabela ma 7200 podmiotów. Patrzę na wyniki w Fiddler i widzę, że próbuje pobrać około 20 MB informacji.

Próbowałem uruchomić to samo zapytanie w przeglądarce Google Chrome i domyślnie uzyskano, że uzyskana odpowiedź jest skompresowana w formacie gzip, z 20 MB do około 500 KB. Więc dedukuję, że Prosty klient OData nie robi żadnej kompresji, i dlatego jest tak niesamowicie powolny.

Ponadto żądanie OData Simple Client prosi o informacje o metadanych, które dodają kolejne 4 MB, podczas gdy Chrome lub proste żądanie HttpClient nie musi wykonywać tego połączenia.

Czy jest coś, co mogę zrobić, aby to poprawić i włączyć kompresję?

Dziękuję.

+0

Mam małe doświadczenie z klientem OData, ale czy istnieje sposób, aby sprawdzić/ustawić/zmodyfikować nagłówek "Accept-Encoding: gzip, deflate" na wychodzące żądanie? To powinno przynajmniej spowodować, że serwer uruchomi się i skompresuje. Miałoby to nadzieję, że klient użyje jakiegoś strumienia, który go rozpakuje. –

+0

@MarvinSmit Dlatego właśnie nie jest to pytanie OData, ale pytanie Simple.Odata - które jest specyficzną biblioteką klienta. Biorąc pod uwagę, że wychodzące żądanie jest zarządzane przez bibliotekę, modyfikowanie go nie jest tak banalne, jak się wydaje (jeśli biblioteka go nie obsługuje). Technikalnie, tak, jeden "po prostu" musi podklasować HttpClient i sprawić, by przesłał informacje nagłówka kompresji ... ale jak to zrobić w SImple.Odata? Jestem w tej samej łodzi;) – TomTom

+0

biorąc pod uwagę powyższy kod, oczekiwałbym "beforesend" -> "Headers.Add" typu akceptacji i dać mu spin? –

Odpowiedz

1

udało mi się w końcu włączyć kompresję i przyspieszyć cały proces. Cała dyskusja można znaleźć tutaj: https://github.com/object/Simple.OData.Client/issues/238

je oddać łatwo i szybko, wystarczy zmodyfikować obsługi wiadomości w instancji ODataSettings z poniższego fragmentu kodu:

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

Teraz httpRequests są wysyłane jako gzip, deflate i zdekompresowane na odpowiedź poprawnie.

1

Jeśli sprawdzasz, które nagłówki wysyłają Chrome i próbujesz je skopiować w języku C#?

Ponadto, jeśli muszę uzyskać dostęp do CRM z C#, użyłbym Microsoft.Xrm.Sdk, a nie OData. Masz mnóstwo typów proxy i żądań, które pozwolą ci napisać o wiele bardziej czysto. OData ma inne ograniczenia, których nie mają również QueryExpressions/CRM LINQ/FetchXml.

OData miałoby więcej sensu dla kodu JS (tj. Żądania z formularza CRM).

2

W swoim działaniu BeforeRequest, dodać nagłówek Accept-Encoding następująco:

settings.BeforeRequest = (request) => 
{ 
    // ... other headers as above 
    request.Headers.Add("Accept-Encoding", "gzip"); 
};