问题描述
我正在处理一个第三方API,该第三方API的调用要求GET方法请求上的Content-Type标头,但是当标头集合包含"Content-Length"时返回错误响应.添加Content-Type标头的唯一方法是添加一个继承/实现IHttpContent接口的类(我使用HttpStringContent并将string.empty作为字符串内容).问题在于,添加空白HttpStringContent会添加ContentLength.即使该标头的值为"0",他们的服务器也会非常生气.在调试时,Content-Length不会显示在标头集合中,但是当我通过Postman或Burp Proxy运行应用程序时,Content-Length标头就在那里.我尝试盲目使用.Remove摆脱Content-Length标头,但这不起作用.
I'm dealing with a third-party API who's calls require the Content-Type header on GET method requests, but return an error response when the header collection includes "Content-Length". The only way to add the Content-Type header is to add a class that inherits/implements the IHttpContent interface (I was using HttpStringContent with string.empty as the string content). The problem, is that adding a blank HttpStringContent adds ContentLength. Even though the value of that header is '0', their server gets super angry. Content-Length doesn't show up in the header collection while i'm debugging, but when i run my application through Postman or Burp Proxy, the Content-Length header is there. I've tried blindly using .Remove to get rid of the Content-Length header but that doesn't work.
我已经看到StackOverflow有关添加Content-Length的问题,但这不是我需要/想要的.有什么方法可以使GET请求中的Content-Type标头,没有具有Content-Length标头?或者....有没有办法删除Content-Length标头?我曾尝试创建自己的实现IHttpContent的内容类,但是我对IAsyncOperationWithProgress的实现陷入了困境.
I've seen StackOverflow questions about adding Content-Length, but that's not what i need/want. Is there any way to have the Content-Type header in a GET request, without having the Content-Length header? Or.... is there a way to remove the Content-Length header? I've tried creating my own content class that implements IHttpContent, but i'm getting stuck with the implementation of IAsyncOperationWithProgress.
我知道这不是标准,这就是为什么我对此有很多困难的原因.我还尝试了Flurl,它也没有添加Content-Type标头.
I understand this isn't standard, which is why i'm having so much difficulty with this. I've also tried Flurl which also didn't add the Content-Type header.
TL; DR:Content-Type(应用程序/json)是必需的,Content-Length会导致API错误(即使它为0).如何在不具有Content-Length的情况下将Content-Type添加到Windows.Web.Http.HttpRequestMessage/HttpClient?
为澄清起见,这是一个UWP应用程序
for clarification this is a UWP application
推荐答案
您已经知道,您需要做一些非标准的事情,所以我提出了一个非标准的解决方案来完成这项工作.
As you're aware, you're needing to do something non-standard, so I present a non-standard solution to get this done.
您可能尝试了client.DefaultRequestHeaders.Add()
和client.DefaultRequestHeaders.TryAddWithoutValidation()
均未成功.您可以使用反射来破坏进入HttpRequestHeaders
的方式来修改验证行为.
You've likely tried client.DefaultRequestHeaders.Add()
and client.DefaultRequestHeaders.TryAddWithoutValidation()
without success. You can use reflection to evil your way into HttpRequestHeaders
to modify the validation behavior.
static void AllowInvalidRequestHeader(string header)
{
var headerType = typeof(HttpRequestHeaders);
var field = headerType
.GetField("invalidHeaders", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Static) ??
headerType
.GetField("s_invalidHeaders", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Static);
if (field == null) return;
var invalidFields = (HashSet<string>)field.GetValue(null);
invalidFields.Remove(header);
}
在应用程序初始化中,调用AllowInvalidRequestHeader("Content-Type")
一次,并使用以下方法初始化HttpClient
实例:
In application initialization, call AllowInvalidRequestHeader("Content-Type")
once, and initialize HttpClient
instances with this:
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Content-Type", "application/json");
在一个简单的服务器端页面中,回显具有请求标头,我回来了:
In a simple server side page that echos have request headers, I get back:
<div class="row">
<p>Connection: Keep-Alive</p>
<p>Content-Type: application/json</p>
<p>Host: localhost:52975</p>
<p>MS-ASPNETCORE-TOKEN: de3a3a58-eccc-407b-b5f7-9a6663631587</p>
<p>X-Original-Proto: http</p>
<p>X-Original-For: 127.0.0.1:53362</p>
</div>
这篇关于(UWP)如何在GET请求中添加不带Content-Length的Content-Type标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!