2013-08-21 7 views
7

Ich verwende RestSharp und Json.NET für die Serialisierung (siehe here).Wie kann ich RestSharp BSON verwenden?

Json.NET unterstützt BSON, und da einige meiner Anfragen riesige Blöcke von Binärdaten enthalten, würde dies meine Anwendung dramatisch beschleunigen. Soweit ich das beurteilen kann, scheint RestSharp keine eingebaute Unterstützung für BSON zu haben.

Die Verwendung von Json.NET ist als benutzerdefinierter Serializer für RestSharp implementiert, und auf den ersten Blick sieht es so aus, als wäre es möglich, diesen benutzerdefinierten Serializer für die Verwendung von BSON zu modifizieren. Aber die Serialize Methode der RestSharp.Serializers.ISerializer Schnittstelle gibt eine string zurück - die (ich nehme an) für BSON ungeeignet ist. Also nehme ich an, dass RestSharp noch einige wichtige Änderungen benötigt, um diese Änderung zu implementieren.

Hat jemand einen Weg gefunden, dies zu tun?


Update: Ich schaute auf die RestSharp Quelle und entdeckt, dass die RestRequest.AddBody Methode, die meine Aufgabe übernimmt und serialisiert sie in die Anforderungs Körper Request.AddParameter schließlich ruft (mit den serialisierten Objektdaten und der Parametertyp RequestBody).

Ich dachte, dass ich in der Lage sein könnte, mein Objekt zu BSON serialisieren und dann Request.AddParameter direkt anrufen - und tatsächlich kann ich. Wenn RestSharp dann jedoch RestRequest ausführt, kann der binäre Inhalt nicht in die Anforderung eingefügt werden, da andere eingebettete Annahmen über den UTF-8-codierten Anforderungsinhalt bestehen.

So sieht es aus wie diesem Hack würde nicht funktionieren - es müssten einige Änderungen vorgenommen werden, sich RestSharp, und ich bin nicht der Mann für den Job ...


Update 2: I Ich entschied mich dafür, den Debugger zu verwenden, um herauszufinden, wie viel von RestSharp ich ändern musste, um das Problem der Körpercodierung zu beheben, also tauschte ich meine NuGet-Version von RestSharp aus und fügte das RestSharp-Projekt in meine Lösung ein. Und ... es arbeitete.

Es stellt sich heraus, dass in den letzten Monaten eine Änderung an RestSharp vorgenommen wurde, die noch nicht in der NuGet-Version enthalten ist.

Also, Sie können jetzt AddParameter verwenden und geben in einem bereits BSON-kodierte Objekt und RestSharp wird es sendet an den Server klaglos ab.

Antwort

6

Per Updates in meiner Frage, stellt sich heraus, dass, wenn Sie die neueste RestSharp Quelle haben, dann statt dessen:

 request.AddBody(myObject); 

... Sie diese stattdessen tun können, wenn Sie eine Nutzlast haben das wäre profitieren von BSON mit:

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

Beachten sie, dass der erste Parameter auf AddParameter Name angeblich der Parameter ist, aber im Fall von ParameterType.RequestBody es tatsächlich als Inhaltstyp verwendet. (Yuk).

Beachten Sie, dass diese auf einen zu RestSharp am 11. April 2013 gemacht change verläßt sich durch ewanmellor/ayoung, und diese Änderung ist nicht in der aktuellen Version auf NuGet (104,1).Daher funktioniert dies nur, wenn Sie die aktuelle RestSharp-Quelle in Ihr Projekt aufnehmen.

3

Garys Antwort auf seine eigene Frage war unglaublich nützlich für das Serialisieren erholsamer Anrufe. Ich wollte beantworten, wie man erholsame Anrufe unter Verwendung JSON.NET deserialize. Ich verwende RestSharp Version 104.4 für Silverlight. Mein Server verwendet Web API 2.1 with BSON support turned on.

Um eine BSON Antwort zu akzeptieren, erstellen Sie eine BSON Deserializer für RestSharp wie so

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

Dann sichern Sie Ihre Anfrage akzeptiert "application/BSON"

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

und einen Handler für die Medien hinzufügen Typ

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

Diese Antwort hat mir sehr geholfen, falls jemand eine Ausnahme bekommt "Sequenz enthält mehr tha n ein Element "Beim Hinzufügen des Handlers habe ich ihn durch Hinzufügen von Handlern korrigiert, bevor ich Standard-Header zur RestClient-Instanz hinzufügte – yvesmancera