7

我正在使用 RestSharp,并使用 Json.NET 进行序列化(请参阅此处)。

Json.NET 支持 BSON,并且由于我的一些请求包含大量二进制数据,我认为这将大大加快我的应用程序的速度。但是,据我所知,RestSharp 似乎没有对 BSON 的任何内置支持。

Json.NET 的使用是作为 RestSharp 的自定义序列化程序实现的,因此乍一看似乎可以修改该自定义序列化程序以使用 BSON。但是,接口的Serialize方法RestSharp.Serializers.ISerializer返回一个string- (我假设)不适合 BSON。因此,我认为需要对 RestSharp 进行一些更重大的更改才能实现此更改。

有没有人想出办法做到这一点?


更新:我查看了 RestSharp 源代码,发现RestRequest.AddBody获取我的对象并将其序列化到请求正文中的方法最终调用Request.AddParameter(使用序列化的对象数据和参数 type RequestBody)。

我想我也许可以将我的对象序列化为 BSON,然后Request.AddParameter直接调用 - 事实上我可以。但是,当 RestSharp 然后执行 时RestRequest,它无法将二进制内容放入请求中,因为还有其他关于请求内容是 UTF-8 编码的嵌入假设。

因此,看起来这种 hack 是行不通的——需要对 RestSharp 本身进行一些更改,而且我不是这个工作的人......


更新 2:我决定尝试使用调试器来确定我必须更改多少 RestSharp 才能克服正文编码问题,所以我换掉了我的 NuGet 版本的 RestSharp 并将 RestSharp 项目包含在我的解决方案。而且……它奏效了。

事实证明,在过去的几个月里,RestSharp 发生了变化,但 NuGet 版本中还没有。

因此,您现在可以使用AddParameter并传入一个已经 BSON 编码的对象,RestSharp 会毫无怨言地将其发送到服务器。

4

2 回答 2

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

请注意,第一个参数 toAddParameter应该是参数名称,但ParameterType.RequestBody实际上它用作内容类型。(玉)。

请注意,这依赖于ewanmellor/ayoung 在 2013 年 4 月 11 日对 RestSharp 所做的更改,并且此更改不在NuGet (104.1) 上的当前版本中。因此,仅当您在项目中包含当前的 RestSharp 源时,这才有效。

于 2013-08-22T11:41:47.340 回答
3

Gary 对他自己问题的回答对于序列化 restful 调用非常有用。我想回答如何使用JSON.NET反序列化 restful 调用。我正在为 Silverlight 使用 RestSharp 104.4 版。我的服务器正在使用启用了 BSON 支持的 Web API 2.1 。

要接受 BSON 响应,请为 RestSharp 创建一个 BSON 反序列化器,如下所示

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

然后,确保您的请求接受“application/bson”

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

并为该媒体类型添加一个处理程序

var client = new RestClient(url);
client.AddHandler("application/bson", new BsonDeserializer());
于 2014-10-27T18:48:11.780 回答