简体   繁体   English

支持.NET OData 4 Client中的压缩

[英]Support compression in .NET OData 4 Client

Problem 问题

I have added support for http compression in our self-hosted OWIN/Katana Web API OData 4 service but I do not see how to support compression in the .NET client. 我在自托管的OWIN / Katana Web API OData 4服务中添加了对HTTP压缩的支持,但是我看不到如何在.NET客户端中支持压缩。 I'm using OData libraries v6.5.0 and I need to support compression/decompression in the client ( OData v4 Client Code Generator ). 我正在使用OData库v6.5.0,并且需要在客户端( OData v4客户端代码生成器 )中支持压缩/解压缩。 I am using Deflate encoding for the compression via an ActionFilter. 我正在使用Deflate编码通过ActionFilter进行压缩。 Everything compresses correctly on the server as confirmed via Fiddler but I do not know how to configure the client to support this now that the OData client uses the Request and Response Pipelines instead of the now defunct WritingRequest and RecievingResponse events that once supported this very scenario . 通过Fiddler确认,服务器上的所有内容均正确压缩,但是由于OData客户端使用请求和响应管道,而不是曾经支持这种情况的现已停产的WritingRequest和RecievingResponse事件,现在我不知道如何配置客户端以支持此操作。

Attempts 尝试次数

By experimentation I found that I can hook into the ReceivingResponse event on my DataServiceContext and then call ReceivingResponseEventArgs.ResponseMessage.GetStream() but I don't know what to do to overwrite the message content correctly. 通过实验,我发现可以挂接到DataServiceContext上的ReceivingResponse事件,然后调用ReceivingResponseEventArgs.ResponseMessage.GetStream(),但是我不知道该怎么做才能正确覆盖消息内容。 If I CopyTo() on the stream, I get a null reference exception at Microsoft.OData.Core.ODataMessageReader.DetectPayloadKind(). 如果我在流上使用CopyTo(),则在Microsoft.OData.Core.ODataMessageReader.DetectPayloadKind()处将获得空引用异常。 I presume this is because the stream was read to the end and the position needs to be set back to zero but I cannot do that because the stream also throws an exception when setting the position back because it says it does not support seeking. 我认为这是因为流被读到末尾并且需要将位置设置为零,但是我不能这样做,因为流将位置设置回时也会抛出异常,因为它说它不支持查找。 I presume this is simply due to the stream being read-only. 我认为这仅仅是由于流是只读的。 Even if I could copy the stream to decompress it successfully, how do I modify the response message content with the decompressed content? 即使我可以复制流以成功对其进行解压缩,如何用解压缩的内容修改响应消息的内容? I don't see any hooks for this at all in the RequestPipeline or ResponsePipeline. 我在RequestPipeline或ResponsePipeline中根本看不到任何钩子。 To clarify, I want to decompress the response message content and then set it for the materialization that occurs soon after, how might I do that? 为了澄清起见,我想解压缩响应消息的内容,然后将其设置为稍后发生的实现,我该怎么做? Extra credit for how to also send compressed requests to the OData service. 有关如何还将压缩的请求发送到OData服务的额外功劳。 Thanks! 谢谢!

OData client use the HTTPWebRequest and HTTPWebReponse, which supports the compression well. OData客户端使用HTTPWebRequest和HTTPWebReponse,它们很好地支持压缩。 Try setting the AutomaticDecompression of HTTPWebRequest to Deflate or GZip, in SendingRequest2 pipeline event, like this: 尝试在SendingRequest2管道事件中将HTTPWebRequest的AutomaticDecompression设置为Deflate或GZip,如下所示:

private void OnSendingRequest_(object sender, SendingRequest2EventArgs args)
{
    if (!args.IsBatchPart) // The request message is not HttpWebRequestMessage in batch part.
    {
        HTTPWebRequest request = ((HttpWebRequestMessage)args.RequestMessage).HttpWebRequest;
        request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
    } 
}

Then in response, HTTPWebResponse will decompress the stream automatically, before the materialization work. 然后,作为响应,HTTPWebResponse将在实现工作之前自动对流进行解压缩。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM