/将一个gzip压缩的主体发布到ASP.NET Web API应用程序主机

时间:2017-06-05 18:16:48

标签: c# asp.net asp.net-web-api gzip iis-8

问题:

Web API 2.2 Controller不会反序列化一个被压缩的POST主体;如果正文未编码,则反序列化而不会出现问题。

问题

当POST主体被gzip压缩时,为什么我的DelegatingHandler不会接收

轶事:

假设我有两个代表序列的服务(A和B)。

+GET/A returns A' +POST/B requires A' and returns B'

  

A.cs

public class AController : ApiController
{
   [HttpGet]
   [Route("A")]
   public HttpResponseMessage GetA()
   {
     APrime _aprime = new APrime("A'");
     return Request.CreateResponse(HttpStatusCode.OK, new[]{_aprime});
   }
}
  

B.cs

public class BController : ApiController
{
   [HttpPost]
   [Route("B")]
   public HttpResponseMessage PostAReturnB([FromBody]IEnumerable<APrime> aprime)
   {
     if(aprime == null)return Request.CreateResponse(HttpStatusCode.BadRequest, "aprime required");
     BPrime _bprime = new BPrime("B'");
     return Request.CreateResponse(HttpStatusCode.OK, new[]{_bprime});
   }
}

无代理处理程序

未编码的通信

/GET+http://localhost:8880/A
Accept: application/json

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 20257
[{...A'...}]


/POST+http://localhost:8880/B
Accept: application/json
Content-Type: application/json
Content-Length: 20257
[{...A'...}]

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 59466
[{...B'...}]

编码通讯

/GET+http://localhost:8880/A
Accept: application/json
Accept-Encoding: gzip

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 4000
<binary data representing a gzip encoded "A'">

/POST+http://localhost:8880/B
Accept: application/json
Content-Type: application/json
Content-Length: 4000
Content-Encoding: gzip
<binary data representing a gzip encoded "A'">

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Content-Length: 15
aprime required

使用委托处理程序

public class MyRequestHandler : DelegatingHandler
{
   protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   {
      if (request.Method == HttpMethod.Post)
      {
         //Do Stuff that checks if the body is compressed.
         //Decompress it
      }
      return base.SendAsync(request, cancellationToken);
   }
}

未编码的通信

调用处理程序,服务正常启动

编码通讯

Handler永远不会开火。 Fiddler显示504

当我终于明白我正在通过我的剪贴板传递我的Response主体时,我以为我有一个A-Ha,所以我尝试在Fiddler中实现一个自定义规则来对清晰的主体内容执行gzip压缩。 / p>

if(oSession.requestBodyBytes != null && (oSession.oRequest.headers.Exists("Client.Request-Encoding")))
{
    oSession["ui-italics"] = "true";
    if(oSession.oRequest["Client.Request-Encoding"] == "gzip")
    {

       oSession.requestBodyBytes = Utilities.GzipCompress(oSession.requestBodyBytes);
       oSession["Content-Length"] = oSession.requestBodyBytes.Length.ToString();

       oSession.oRequest["Client.CustomRule"] = "[Fiddler][Custom Rule.GZip]";

       oSession["ui-color"] = "green";
       oSession["ui-italics"] = "false";
       oSession["ui-bold"] = "true";
    }else{
       oSession["ui-color"] = "crimson";
       oSession["ui-italics"] = "true";
       oSession.oRequest["Client.Request-Encoding.Error"] = "Rule not processed. gzip is the only supported Request-Encoding value";
    }
}

我通过此规则处理的请求只是进入下层。

0 个答案:

没有答案