(UWP)如何在GET请求中添加没有Content-Length的Content-Type标头

时间:2018-04-01 20:11:14

标签: c# .net uwp http-headers httprequest

我正在处理第三方API,他们的调用需要GET方法请求上的Content-Type标头,但当标头集合包含" Content-Length&#时会返回错误响应34 ;.添加Content-Type标头的唯一方法是添加一个继承/实现IHttpContent接口的类(我使用HttpStringContent和string.empty作为字符串内容)。问题是,添加一个空白的HttpStringContent会添加ContentLength。即使该标题的值为' 0',他们的服务器也会非常生气。在我调试时,Content-Length并没有出现在标题集中,但是当我通过Postman或Burp Proxy运行我的应用程序时,Content-Length标题就在那里。我试图盲目地使用.Remove去掉Content-Length标题,但这不起作用。

我已经看到StackOverflow有关添加Content-Length的问题,但这不是我需要/想要的。有没有办法在GET请求中使用Content-Type标头,没有具有Content-Length标头?或....有没有办法删除Content-Length标题?我尝试创建自己的实现IHttpContent的内容类,但我对IAsyncOperationWithProgress的实现感到困惑。

我知道这不是标准,这就是为什么我有这么多困难的原因。我也尝试过Flurl,它也没有添加Content-Type标题。

TL; DR:Content-Type(application / json)是必需的,并且API错误中的Content-Length结果(即使它是0)。如何在没有Content-Length的情况下将Content-Type添加到Windows.Web.Http.HttpRequestMessage / HttpClient?

编辑:澄清这是一个UWP应用程序

1 个答案:

答案 0 :(得分:2)

正如您所知,您需要做一些非标准的事情,所以我提出了一个非标准的解决方案来完成这项工作。

您可能尝试client.DefaultRequestHeaders.Add()client.DefaultRequestHeaders.TryAddWithoutValidation()但未成功。您可以在HttpRequestHeaders中使用反射到邪恶来修改验证行为。

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个实例:

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Content-Type", "application/json");

在echos有请求标题的简单服务器端页面中,我回来了:

<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>