2013-08-21 26 views
7

Sto utilizzando RestSharp e utilizzo di Json.NET per la serializzazione (vedere here).Come posso fare in modo che RestSharp usi BSON?

Json.NET supporta BSON, e poiché alcune delle mie richieste hanno enormi blocchi di dati binari, penso che ciò velocizzerebbe la mia applicazione in modo drammatico. Tuttavia, per quanto posso dire, RestSharp non sembra avere alcun supporto integrato per BSON.

L'uso di Json.NET è implementato come serializzatore personalizzato per RestSharp, e quindi a prima vista sembra che sarebbe possibile modificare quel serializzatore personalizzato per utilizzare BSON. Ma, il metodo Serialize dell'interfaccia RestSharp.Serializers.ISerializer restituisce un string - che è (presumo) inadatto per BSON. Quindi, presumo che ci vorranno alcune modifiche più significative a RestSharp per implementare questo cambiamento.

Qualcuno ha trovato un modo per farlo?


Aggiornamento: Ho guardato la fonte RestSharp, e ha scoperto che il metodo RestRequest.AddBody che prende il mio scopo e serializza in corpo della richiesta alla fine chiama Request.AddParameter (con i dati dell'oggetto serializzati, e il tipo di parametro RequestBody).

Ho pensato che avrei potuto serializzare il mio oggetto su BSON e quindi chiamare direttamente lo Request.AddParameter - e in effetti posso farlo. Tuttavia, quando RestSharp esegue quindi RestRequest, non riesce a inserire il contenuto binario nella richiesta, poiché esistono altre ipotesi incorporate sul contenuto della richiesta codificato in UTF-8.

Così sembra che questo hack non funzionerebbe - non ci sarebbe bisogno di essere alcune modifiche apportate al RestSharp sé, e io non sono l'uomo per il lavoro ...


Update 2: I Ho deciso di provare a utilizzare il debugger per capire quanto di RestSharp dovrei cambiare per superare il problema di codifica del corpo, quindi ho sostituito la versione NuGet di RestSharp e ho incluso il progetto RestSharp nella mia soluzione. E ... è lavorato.

Si scopre che c'è stato un cambiamento in RestSharp negli ultimi mesi che non è ancora nella versione NuGet.

Quindi, è possibile ora utilizzare AddParameter e passare un oggetto già BSON codificato, e RestSharp invierà via al server senza lamentarsi.

risposta

6

Per gli aggiornamenti in mia domanda, si scopre che se avete l'ultima fonte RestSharp, allora invece di questo:

 request.AddBody(myObject); 

... si può fare questo, invece ogni volta che avete un carico utile che avrebbe trarre vantaggio dall'utilizzo di 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); 
      } 
     } 

si noti che il primo parametro a AddParameter è presumibilmente il nome del parametro, ma nel caso di ParameterType.RequestBody in realtà è usato come il tipo di contenuto. (Che schiffo).

Si noti che questa si basa su un change fatto per RestSharp in data 11 aprile 2013, ewanmellor/ayoung, e questo cambiamento è non nella versione corrente sul NuGet (104,1).Quindi questo funzionerà solo se includi la sorgente RestSharp corrente nel tuo progetto.

3

La risposta di Gary alla sua stessa domanda è stata incredibilmente utile per la serializzazione di chiamate riposanti. Volevo rispondere a come deserializzare le chiamate riposanti usando JSON.NET. Sto usando RestSharp versione 104.4 per Silverlight. Il mio server utilizza Web API 2.1 with BSON support turned on.

Per accettare una risposta BSON, creare un BSON Deserializer per RestSharp in questo modo

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

Quindi, verificare la richiesta accetta "application/BSON"

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

E aggiungere un gestore per che i media tipo

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

Questa risposta mi ha aiutato molto, nel caso qualcuno ottenga un'eccezione "La sequenza contiene più di n un elemento "quando aggiungo il gestore, l'ho risolto aggiungendo i gestori prima di aggiungere intestazioni predefinite all'istanza RestClient – yvesmancera

Problemi correlati