POST 执行 PostMultipartAsync 时正文为空

POST body null when performing PostMultipartAsync

深入研究使用 flurl 向客户端服务器发送多部分 POST 调用。不幸的是,他们的服务器对我们来说是一个黑盒子。我收到了一条 400 回复,其中包含一条通用消息,所以在我打扰他们之前,我需要了解我的所有基础。

执行这样的调用:

string s = await "https://clientservier.com/cgi-bin/perl-script"
    .PostMultipartAsync(mp => mp
        .AddString("DisplayActive", "IsDisplayed")
        .AddString("ControlTypeHidden", "ALL")
        .AddString("QueryHidden", "KEYs")
        .AddString("dump_app_trace", "false")
        .AddString("db_debug", "false")
        .AddString("Get Data", "Get Data"))
    .ReceiveString();

如果我在 BeforeCall 事件上附加一个处理程序,并查看 HttpCall 对象,我的变量将按预期列在 Request.Content.Parts 中。但是,RequestBody 为空 - 我想查看已发送请求的字符串输出,类似于:

-----------------------------13377838992432022416720759
Content-Disposition: form-data; name="DisplayActive"

IsDisplayed
-----------------------------13377838992432022416720759
Content-Disposition: form-data; name="ControlTypeHidden"

ALL
-----------------------------13377838992432022416720759
Content-Disposition: form-data; name="QueryHidden"

KEYs
-----------------------------13377838992432022416720759
Content-Disposition: form-data; name="Get Data"

Get Data
-----------------------------13377838992432022416720759
Content-Disposition: form-data; name="dump_app_trace"

false
-----------------------------13377838992432022416720759
Content-Disposition: form-data; name="db_debug"

false
-----------------------------13377838992432022416720759--

(显然,是的,边界会有所不同,这只是一个浏览器示例。) 有趣的是,当调用返回 400 时,AfterCall 事件处理程序在对象中没有上述部分,所以我想知道我是否忘记在进行此调用之前做某事。

在这种情况下 RequestBody 为 null 绝对不符合直觉。在 HttpClient 堆栈中,请求主体基本上是 read-once 流,如果您需要进行诊断,则很难将其作为字符串读回。 Flurl 基本上说,是的,在大多数典型情况下,这可能是 micro-optimization,例如 JSON 或 URL-encoded POST,其中请求正文往往不是很大。所以在内部它使用一种叫做 CapturedStringContent 的类型,它只是在构造时将字符串“捕获”到 属性。事件处理程序使用它来公开 RequestBody 属性.

但是多部分请求更有可能很大,捕获字符串中的请求正文可能是一个合理的内存问题。所以这里使用的类型不是从 CapturedStringContent 派生的,因此你不能轻易地以字符串形式获取正文。

至于为什么 Parts 是空的,HttpClient(Flurl 构建在上面)disposes the HttpContent object automatically after the request is sent. Strangely (in my opinion), this clears the underlying collection that Parts comes from, which I confirmed in the source

综上所述,您的代码对我来说看起来不错,我毫不怀疑它正在做您期望的事情。但如果你想绝对确定,我建议使用像 Fiddler 或 Wireshark 这样的网络嗅探器。