C# ASP.NET Web API 2.2应用程序赢得';无法激活POST请求 破败
注意:我的本地服务器是IISExpress。我还没有尝试将我的应用程序部署到IIS,因为我无法在本地生成所需的行为 我正在尝试将一个已从客户端压缩到Web API的主体发布到我的Web API中。C# ASP.NET Web API 2.2应用程序赢得';无法激活POST请求 破败,c#,asp.net,iis,gzip,C#,Asp.net,Iis,Gzip,注意:我的本地服务器是IISExpress。我还没有尝试将我的应用程序部署到IIS,因为我无法在本地生成所需的行为 我正在尝试将一个已从客户端压缩到Web API的主体发布到我的Web API中。 我可以通过简单地与IIS通信得到gzip响应myAccept Encoding:gzip,但发送gzip请求体的问题要大得多 我尝试通信Content Encoding:gzip,并将gzip响应复制粘贴到我的请求主体中(这显然不起作用,因为我在剪贴板中移动二进制文件时通过Unicode传递了它)
我可以通过简单地与IIS通信得到gzip响应my
Accept Encoding:gzip
,但发送gzip请求体的问题要大得多
我尝试通信Content Encoding:gzip
,并将gzip响应复制粘贴到我的请求主体中(这显然不起作用,因为我在剪贴板中移动二进制文件时通过Unicode传递了它)
我尝试在服务器上的
配置块中添加
动态类型列表
我尝试将此配置复制到应用程序的web.config中的
配置块
我尝试创建一个定制的DelegatingHandler,并添加了一个客户端Fiddler规则,允许我将Unicode-json粘贴到请求主体中,并让Fiddler在请求发出之前执行GZip压缩
所有这些都不允许我的客户机发送gzip主体,以便服务器接收和解压缩
另请注意:我的帖子正文的内容类型是application/json
。当我发送我的GZip正文(下面的细节第2节)时,我收到了一个关于头中GZip幻数的错误。这是将[copy+pasted]内容从一个Fiddler响应复制到后续的Fiddler请求中,因此二进制内容通过剪贴板传递。在将其复制到剪贴板时,如果将其转换为Unicode,则可能会失败。最相关的一点是,它会生成一个显式的服务器错误;服务器通过响应一个内部服务器错误来确认它
最后注意:使用DelegatingHandler和对Utilities.gzip compress()
的客户端调用,服务器永远不会确认收到请求。如果我注释掉压缩行,服务器将确认该请求
这是什么原因造成的?
这是如何纠正的?
细节
这就是让我来到这里的原因:
1] 我可以简单地请求接受编码:gzip
,IIS通过gzip响应来满足我的请求。在对
进行任何配置更改或添加DelegatingHandler之前,我首先尝试根据不同的请求将此gzip内容发布回服务器,同时与content Encoding:gzip
进行通信,我的应用程序激活了相应的控制器,并将我的请求路由到相应的控制器,但主体不会反序列化,表面上是因为它试图将压缩的二进制数据视为明文Content-Type:application/json
。我的客户(Fiddler)收到一个400错误请求
注意,为了将gzip响应链接到测试请求的主体,我通过剪贴板传递了二进制数据。我知道这不会“只起作用”(通过剪贴板通过UTF-8传输二进制数据-我认为..也许UTF-16…不太重要),但我想看看我实际会得到什么行为。重要的是,IIS和ASP.NET似乎完全忽略了我的内容编码
标题
2] 然后,我在applicationHost.config中修改了httpCompression
,以包括application/json
和application/json;charset=utf8
在我的支持动态压缩的类型列表中
<httpCompression directory="%TEMP%\iisexpress\IIS Temporary Compressed Files">
<scheme name="gzip" dll="%IIS_BIN%\gzip.dll" />
<dynamicTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/javascript" enabled="true" />
<add mimeType="application/atom+xml" enabled="true" />
<add mimeType="application/xaml+xml" enabled="true" />
<add mimeType="application/json" enabled="true" />
<add mimeType="application/json; charset=utf-8" enabled="true" />
<add mimeType="*/*" enabled="false" />
</dynamicTypes>
<staticTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="image/svg+xml" enabled="true" />
<add mimeType="application/javascript" enabled="true" />
<add mimeType="application/atom+xml" enabled="true" />
<add mimeType="application/xaml+xml" enabled="true" />
<add mimeType="*/*" enabled="false" />
</staticTypes>
</httpCompression>
//+================================================================================+
//|[KAB] Trying to have Fiddler compress the clear Body prior to request. |
//| Rationale: POSTing a gzipped response as a Request body is generating |
//| an internal server error |
//| +--------------------------------------------------------------------------+ |
//| |The magic number in GZip header is not correct. Make sure you are passing | |
//| |in a GZip stream. | |
//| +--------------------------------------------------------------------------+ |
//| Goal is to see if passing through the clipboard is what is generating this |
//+================================================================================+
if(oSession.requestBodyBytes != null && (oSession.oRequest.headers.Exists("Client.Request-Encoding")))
{
if(oSession.oRequest["Client.Request-Encoding"] == "gzip")
{
//+=================================================+
//|Commenting these 2 lines prevents the Compression
//|from actually occurring. When I disable compression
//|of requestBodyBytes, the request goes out and is
//|serviced as an uncompressed body by my application
//|-------------------------------------------------
oSession.requestBodyBytes = Utilities.GzipCompress(oSession.requestBodyBytes);
oSession["Content-Length"] = oSession.requestBodyBytes.Length.ToString();
//|-------------------------------------------------
//+=================================================+
oSession["ui-color"] = "green";
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";
}
}
3] 我在我的合成空间中引入了一个DelegatingHandler,它只在POST请求时触发
CompressedRequestHandler.cs
我还在Fiddler中引入了一个CustomRule,用于在BeforeRequest上执行客户端压缩,有两种排列(用于测试规则本身)
1] 实际执行身体的GZip压缩
2] 激发规则,但不执行压缩
<httpCompression directory="%TEMP%\iisexpress\IIS Temporary Compressed Files">
<scheme name="gzip" dll="%IIS_BIN%\gzip.dll" />
<dynamicTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/javascript" enabled="true" />
<add mimeType="application/atom+xml" enabled="true" />
<add mimeType="application/xaml+xml" enabled="true" />
<add mimeType="application/json" enabled="true" />
<add mimeType="application/json; charset=utf-8" enabled="true" />
<add mimeType="*/*" enabled="false" />
</dynamicTypes>
<staticTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="image/svg+xml" enabled="true" />
<add mimeType="application/javascript" enabled="true" />
<add mimeType="application/atom+xml" enabled="true" />
<add mimeType="application/xaml+xml" enabled="true" />
<add mimeType="*/*" enabled="false" />
</staticTypes>
</httpCompression>
//+================================================================================+
//|[KAB] Trying to have Fiddler compress the clear Body prior to request. |
//| Rationale: POSTing a gzipped response as a Request body is generating |
//| an internal server error |
//| +--------------------------------------------------------------------------+ |
//| |The magic number in GZip header is not correct. Make sure you are passing | |
//| |in a GZip stream. | |
//| +--------------------------------------------------------------------------+ |
//| Goal is to see if passing through the clipboard is what is generating this |
//+================================================================================+
if(oSession.requestBodyBytes != null && (oSession.oRequest.headers.Exists("Client.Request-Encoding")))
{
if(oSession.oRequest["Client.Request-Encoding"] == "gzip")
{
//+=================================================+
//|Commenting these 2 lines prevents the Compression
//|from actually occurring. When I disable compression
//|of requestBodyBytes, the request goes out and is
//|serviced as an uncompressed body by my application
//|-------------------------------------------------
oSession.requestBodyBytes = Utilities.GzipCompress(oSession.requestBodyBytes);
oSession["Content-Length"] = oSession.requestBodyBytes.Length.ToString();
//|-------------------------------------------------
//+=================================================+
oSession["ui-color"] = "green";
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";
}
}
这会让你了解运动部件的速度
当我注释掉执行对gzip压缩(oSession.requestBodyBytes)
的调用的规则行时,我的应用程序被唤醒,我的DelegatingHandler被触发,一切都像请求未压缩一样处理。只要这些行被启用,我的请求就会被GZip压缩(通过Composer确认),但我的应用程序从未收到请求。委托人从不开枪
你能展示Api控制器的POST方法吗?这听起来像是压缩使请求正文看起来像是控制器不希望看到的东西。@David我可以显示POST方法,但在HttpRouteDispatcher和ASP.NET未根据正文内容路由POST请求之前,DelegatingHandler会启动,因此我认为这与我的问题无关。如果-在阅读之后-你仍然有一个特定的好奇心,你觉得可能是相关的,请让我知道,我会编辑更新
//+================================================================================+
//|[KAB] Trying to have Fiddler compress the clear Body prior to request. |
//| Rationale: POSTing a gzipped response as a Request body is generating |
//| an internal server error |
//| +--------------------------------------------------------------------------+ |
//| |The magic number in GZip header is not correct. Make sure you are passing | |
//| |in a GZip stream. | |
//| +--------------------------------------------------------------------------+ |
//| Goal is to see if passing through the clipboard is what is generating this |
//+================================================================================+
if(oSession.requestBodyBytes != null && (oSession.oRequest.headers.Exists("Client.Request-Encoding")))
{
if(oSession.oRequest["Client.Request-Encoding"] == "gzip")
{
//+=================================================+
//|Commenting these 2 lines prevents the Compression
//|from actually occurring. When I disable compression
//|of requestBodyBytes, the request goes out and is
//|serviced as an uncompressed body by my application
//|-------------------------------------------------
oSession.requestBodyBytes = Utilities.GzipCompress(oSession.requestBodyBytes);
oSession["Content-Length"] = oSession.requestBodyBytes.Length.ToString();
//|-------------------------------------------------
//+=================================================+
oSession["ui-color"] = "green";
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";
}
}