【问题标题】:(UWP) How to add Content-Type header without Content-Length in GET request(UWP) 如何在 GET 请求中添加没有 Content-Length 的 Content-Type 标头
【发布时间】:2018-04-02 10:47:52
【问题描述】:

我正在与第三方 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 标头,但这不起作用。

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

我知道这不是标准的,这就是为什么我在这方面遇到这么多困难。我也试过 Flurl,它也没有添加 Content-Type 标头。

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

编辑:为澄清起见,这是一个 UWP 应用程序

【问题讨论】:

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


    【解决方案1】:

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

    您可能已经尝试过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");
    

    在回显具有请求标头的简单服务器端页面中,我返回:

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

    【讨论】:

    • 嗯.... :( 我仍然在 Add 方法上收到 A method was called at an unexpected time. Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.
    • 可以确认AllowInvalidRequestHeader 确实确实从集合中删除了“Content-Type”。
    • 为了澄清这是一个 UWP 应用程序。反射方法没有异常,但是HttpClient的实例还是拒绝添加Content-Type
    • 在查看了您的建议后,我意识到这一点。我现在没有设置 UWP 开发环境的便捷方法,因此我无法就如何继续提供其他确定的建议。
    • 反射似乎不适用于 UWP(COM 对象)。想我记得在运行时读过一些关于 COM 对象问题的内容。我创建了自己的自定义解决方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 2014-04-25
    • 1970-01-01
    • 2018-04-06
    • 2019-11-21
    相关资源
    最近更新 更多