2013-08-21 16 views
7

Używam RestSharp, i przy użyciu Json.NET do serializacji (patrz here).Jak mogę sprawić, aby RestSharp używał BSON?

Json.NET obsługuje BSON, a ponieważ niektóre z moich żądań mają ogromne bloki danych binarnych, myślę, że to znacznie przyspieszyłoby moją aplikację. Jednak, o ile wiem, RestSharp nie ma wbudowanej obsługi BSON.

Użycie Json.NET jest implementowane jako niestandardowy serializer dla RestSharp, więc na pierwszy rzut oka wygląda na to, że można zmodyfikować ten niestandardowy serializator do korzystania z BSON. Ale metoda Serialize interfejsu zwraca wartość string - która jest (moim zdaniem) nieodpowiednia dla BSON. Zakładam więc, że RestSharp wprowadzi kilka znaczących zmian, aby wprowadzić tę zmianę.

Czy ktoś wymyślił sposób, aby to zrobić?


Aktualizacja: Spojrzałem na źródła RestSharp i odkrył, że metoda RestRequest.AddBody że ma mój obiekt i serializes go do organizmu żądanie ostatecznie nazywa Request.AddParameter (z serializowanych danych obiektowych, a typ parametru RequestBody).

Doszedłem do wniosku, że mogę przetworzyć mój obiekt na BSON, a następnie zadzwonić pod numer Request.AddParameter - i rzeczywiście mogę. Jednak, gdy RestSharp wykonuje następnie RestRequest, nie umieszcza zawartości binarnej w żądaniu, ponieważ istnieją inne założone założenia dotyczące treści żądania, która jest kodowana w UTF-8.

Zatem wygląda na to włamania nie będzie działać - nie musiałyby być jakieś zmiany dokonane RestSharp się, a ja nie jestem człowiekiem do tego zadania ...


Aktualizacja 2: zdecydowałem, że będę musiał użyć debuggera, aby dowiedzieć się, ile RestSharp musiałbym zmienić, aby rozwiązać problem kodowania ciała, więc zamieniłem moją wersję RestSharp na NuGet i zawarłem projekt RestSharp w moim rozwiązaniu. I ... to pracował.

Okazuje się, że nastąpiła zmiana w RestSharp w ciągu ostatnich kilku miesięcy, która nie jest jeszcze w wersji NuGet.

Tak więc, ty możesz teraz używać teraz użyć AddParameter i przekazać obiekt już zakodowany BSON, a RestSharp wyśle ​​go na serwer bez skargi.

Odpowiedz

6

Per aktualizacji w moim pytaniu, okazuje się, że jeśli masz najnowszą źródło RestSharp, wtedy zamiast tego:

 request.AddBody(myObject); 

... można to zrobić, a nie gdy masz ładowność, która skorzystać z systemu BSON:

 using (var memoryStream = new System.IO.MemoryStream()) 
     { 
      using (var bsonWriter = new Newtonsoft.Json.Bson.BsonWriter(memoryStream)) 
      { 
       var serializer = new Newtonsoft.Json.JsonSerializer(); 

       serializer.Serialize(bsonWriter, myObject); 

       var bytes = memoryStream.ToArray(); 

       request.AddParameter("application/bson", bytes, RestSharp.ParameterType.RequestBody); 
      } 
     } 

Zauważ, że pierwszy parametr do AddParameter jest podobno nazwa parametru, ale w przypadku ParameterType.RequestBody to faktycznie używany jako typ zawartości. (Yuk).

Zauważ, że ten opiera się na change złożony do RestSharp w dniu 11 kwietnia 2013 roku przez ewanmellor/Ayoung, a zmiana ta jest nie w obecnej wersji na Nuget (104,1).Stąd będzie to działało tylko wtedy, gdy uwzględnisz obecne źródło RestSharp w swoim projekcie.

3

Odpowiedź Gary'ego na jego własne pytanie była niesamowicie przydatna do serializowania spokojnych rozmów. Chciałem odpowiedzieć na pytanie, jak deserializować spokojne połączenia za pomocą JSON.NET. Korzystam z wersji RestSharp w wersji 104.4 dla Silverlight. Mój serwer używa interfejsu Web API 2.1 with BSON support turned on.

Aby zaakceptować odpowiedź BSON utwórz BSON Deserializator dla RestSharp jak tak

public class BsonDeserializer : IDeserializer 
{ 
    public string RootElement { get; set; } 
    public string Namespace { get; set; } 
    public string DateFormat { get; set; } 

    public T Deserialize<T>(IRestResponse response) 
    { 
     using (var memoryStream = new MemoryStream(response.RawBytes)) 
     { 
      using (var bsonReader = new BsonReader(memoryStream)) 
      { 
       var serializer = new JsonSerializer(); 
       return serializer.Deserialize<T>(bsonReader); 
      } 
     } 
    } 
} 

Następnie zapewnić żądania akceptuje „application/bson”

var request = new RestRequest(apiUrl, verb); 
request.AddHeader("Accept", "application/bson"); 

i dodać obsługi dla tego nośnika typ

var client = new RestClient(url); 
client.AddHandler("application/bson", new BsonDeserializer()); 
+0

Ta odpowiedź bardzo mi pomogła, na wypadek gdyby ktoś dostał wyjątek "Sekwencja zawiera więcej" n jeden element "podczas dodawania handler'a, naprawiłem go dodając Handlers przed dodaniem Default Headers do instancji RestClient – yvesmancera