如何使用 C# HttpClient 发送未编码的表单数据
How to send unencoded form data with C# HttpClient
我正在尝试 "repurpose" 桌面应用程序使用的第三方 API。我发现下面的代码让我非常接近匹配应用程序发送的数据包:
var formData = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>(JsonConvert.SerializeObject(myPayload), "")
});
var response = Client.PostAsync(myURL, formData).Result;
var json = response.Content.ReadAsStringAsync().Result;
这让我得到了应用程序发送的几乎完全相同的有效负载,除了它对数据进行编码(我知道,"encoded" 就在名称中)。我需要得到完全相同的请求,但没有对数据进行编码,但我无法找到合适的对象来实现它。如何防止此有效负载被 URL 编码?
编辑:
这是我从应用程序发出的 Wireshark 中提取的登录请求:
POST /Login HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: 1.1.1.1
Content-Length: 161
Expect: 100-continue
Connection: Close
{"username":"myuser","auth-id":"0a0a140f81a2ce0c303386e93cec41bf04660c22a881be9a"}
以上将生成以下内容:
POST /Login HTTP/1.1
Expect: 100-continue
Connection: Close
Content-Type: application/x-www-form-urlencoded
Content-Length: 221
Host: 1.1.1.1
%7B%22user-name%22%3A%22myuser%22%2C%22auth-id%22%3A%220a0a140f81a2ce0c303386e93cec41bf04660c22a881be9a%22%7D=
为简洁起见,我对它们进行了编辑,因此 Content-Length 是错误的。我意识到这可能不是发送此数据的最佳方式,但我无法控制它的使用方式。
由于您实际上是在尝试发送 JSON,我认为您需要将 JSON 包装在 StringContent
object 而不是 FormUrlEncoded [=28] =]. Form-encoded 数据和 JSON 数据是格式化负载的两种不同方式(例如,另一种常用格式是 XML)。一起使用它们没有任何意义。
我认为这样的事情应该可行:
var content = new StringContent(JsonConvert.SerializeObject(myPayload), Encoding.UTF8, "application/json");
var response = Client.PostAsync(myURL, content).Result;
var json = response.Content.ReadAsStringAsync().Result;
(P.S。应用程序发送的 Content-Type: application/x-www-form-urlencoded
header 似乎具有误导性,因为请求 body 明确包含 JSON。大概是接收服务器容忍这种废话,或者只是忽略它,因为它总是期待 JSON。)
我正在尝试 "repurpose" 桌面应用程序使用的第三方 API。我发现下面的代码让我非常接近匹配应用程序发送的数据包:
var formData = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>(JsonConvert.SerializeObject(myPayload), "")
});
var response = Client.PostAsync(myURL, formData).Result;
var json = response.Content.ReadAsStringAsync().Result;
这让我得到了应用程序发送的几乎完全相同的有效负载,除了它对数据进行编码(我知道,"encoded" 就在名称中)。我需要得到完全相同的请求,但没有对数据进行编码,但我无法找到合适的对象来实现它。如何防止此有效负载被 URL 编码?
编辑:
这是我从应用程序发出的 Wireshark 中提取的登录请求:
POST /Login HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: 1.1.1.1
Content-Length: 161
Expect: 100-continue
Connection: Close
{"username":"myuser","auth-id":"0a0a140f81a2ce0c303386e93cec41bf04660c22a881be9a"}
以上将生成以下内容:
POST /Login HTTP/1.1
Expect: 100-continue
Connection: Close
Content-Type: application/x-www-form-urlencoded
Content-Length: 221
Host: 1.1.1.1
%7B%22user-name%22%3A%22myuser%22%2C%22auth-id%22%3A%220a0a140f81a2ce0c303386e93cec41bf04660c22a881be9a%22%7D=
为简洁起见,我对它们进行了编辑,因此 Content-Length 是错误的。我意识到这可能不是发送此数据的最佳方式,但我无法控制它的使用方式。
由于您实际上是在尝试发送 JSON,我认为您需要将 JSON 包装在 StringContent
object 而不是 FormUrlEncoded [=28] =]. Form-encoded 数据和 JSON 数据是格式化负载的两种不同方式(例如,另一种常用格式是 XML)。一起使用它们没有任何意义。
我认为这样的事情应该可行:
var content = new StringContent(JsonConvert.SerializeObject(myPayload), Encoding.UTF8, "application/json");
var response = Client.PostAsync(myURL, content).Result;
var json = response.Content.ReadAsStringAsync().Result;
(P.S。应用程序发送的 Content-Type: application/x-www-form-urlencoded
header 似乎具有误导性,因为请求 body 明确包含 JSON。大概是接收服务器容忍这种废话,或者只是忽略它,因为它总是期待 JSON。)