2013-08-21 6 views
7

Я использую RestSharp и использую Json.NET для сериализации (см. here).Как заставить RestSharp использовать BSON?

Json.NET поддерживает BSON, и поскольку некоторые из моих запросов имеют огромные блоки двоичных данных, я думаю, что это значительно ускорит мое приложение. Однако, насколько я могу судить, у RestSharp нет встроенной поддержки BSON.

Использование Json.NET реализовано как пользовательский сериализатор для RestSharp, и, на первый взгляд, похоже, что этот пользовательский сериализатор может использовать BSON. Но метод Serialize интерфейса RestSharp.Serializers.ISerializer возвращает string - который (я полагаю) не подходит для BSON. Поэтому я предполагаю, что для внесения изменений в RestSharp потребуются более значительные изменения.

Кто-нибудь понял способ сделать это?


Обновление: Я посмотрел на источнике RestSharp, и обнаружил, что RestRequest.AddBody метода, который принимает мой объект и упорядочивает его в тело запроса в конечном счете вызывает Request.AddParameter (с данными сериализованным объектом, и типом параметра RequestBody).

Я понял, что я мог бы сериализовать свой объект на BSON, а затем напрямую позвонить Request.AddParameter - и действительно могу. Однако, когда RestSharp затем выполняет команду RestRequest, он не может поместить двоичный контент в запрос, потому что есть другие встроенные предположения о том, что контент запроса кодируется UTF-8.

Таким образом, это выглядит, как этот хак не будет работать - там должны были бы быть какие-то изменения, сделанные в RestSharp себя, и я не тот человек, на работу ...


Update 2: Я решил пойти на использование отладчика, чтобы выяснить, сколько из RestSharp мне пришлось бы изменить, чтобы преодолеть проблему кодирования тела, поэтому я поменял свою версию RestSharp на NuGet и включил проект RestSharp в свое решение. И ... это работал.

Оказалось, что за последние несколько месяцев в RestSharp произошли изменения, которых еще нет в версии NuGet.

Таким образом, вы можете теперь использовать AddParameter и передать в уже BSON кодировке объекта, и RestSharp будет отправить его на сервер без жалоб.

ответ

6

За обновлениями в моем вопросе, то получается, что если у вас есть последний источник RestSharp, то вместо этого:

 request.AddBody(myObject); 

... Вы можете сделать это вместо того, чтобы каждый раз, когда у вас есть полезная нагрузка, которая будет выгоды от использования 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); 
      } 
     } 

Обратите внимание, что первый параметр AddParameter предположительно имя параметра, но в случае ParameterType.RequestBody это фактически используется как тип контента. (Юк).

Обратите внимание, что это зависит от change сделал для RestSharp 11 апреля 2013 года по ewanmellor/ayoung, и это изменение не в текущей версии на NuGet (104,1).Следовательно, это будет работать, только если вы включите текущий источник RestSharp в свой проект.

3

Ответ Гэри на свой вопрос был невероятно полезен для сериализации спокойных вызовов. Я хотел ответить, как десериализовать спокойные звонки, используя JSON.NET. Я использую RestSharp версии 104.4 для Silverlight. Мой сервер использует Web API 2.1 with BSON support turned on.

Чтобы принять ответ BSON, создать BSON десериализатор для RestSharp как так

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

Затем убедитесь, ваш запрос принимает "приложения/BSON"

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

И добавить обработчик для этого носителя тип

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

Этот ответ мне очень помог, на случай, если кто-то получит исключение. «Последовательность содержит больше tha n один элемент "при добавлении обработчика, я исправил его, добавив обработчики перед добавлением заголовков Default в экземпляр RestClient – yvesmancera