C# 中的 curl -F 等价物
Curl -F equivalent in C#
我正在尝试使用 C# 中的 HTTPClient 对象将 post 请求发送到 API。
这是 CURL 命令:
curl -X POST https://zzz.zzz.zzz/yyy -F Key=abcd -F media=@"audio.aac"
我写了下面的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.IO;
using System.Net.Http.Headers;
namespace Speech2Text
{
class Program
{
static void Main(string[] args)
{
curl().Wait();
}
static async Task curl()
{
var client = new HttpClient();
//Create List of KeyValuePairs
List<KeyValuePair<string, string>> bodyProperties = new List<KeyValuePair<string, string>>();
bodyProperties.Add(new KeyValuePair<string, string>("key", "abcd"));
bodyProperties.Add(new KeyValuePair<string, string>("media", "@audio.aac"));
var dataContent = new FormUrlEncodedContent(bodyProperties.ToArray());
HttpResponseMessage response = await client.PostAsync("https://zzz.zzz.zzz/yyy", dataContent);
HttpContent responseContent = response.Content;
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
Console.WriteLine(await reader.ReadToEndAsync());
}
}
}
}
但我一直收到这个:
{"code":400,"message":"Please use [media] for the media file field name in your POST request."}
dataContect 变量是否有任何问题或其他问题?
发送 POST 时,重要的是您发送到服务器的 Content-Type 确实是服务器所期望的类型。您可以使用 curl:
中的 -trace
选项轻松验证发送的内容
curl -v --trace - -X POST http://localhost -F Key=abcd -F media=@"image.txt"
当你 运行 时,你会在前几行的某个地方找到这个:
00b0: 63 6f 6e 74 69 6e 75 65 0d 0a 43 6f 6e 74 65 6e continue..Conten
00c0: 74 2d 54 79 70 65 3a 20 6d 75 6c 74 69 70 61 72 t-Type: multipar
00d0: 74 2f 66 6f 72 6d 2d 64 61 74 61 3b 20 62 6f 75 t/form-data; bou
00e0: 6e 64 61 72 79 3d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ndary=----------
00f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0100: 2d 2d 61 61 62 64 66 31 66 66 38 35 66 66 0d 0a --aabdf1ff85ff..
0110: 0d 0a ..
所以 curl 正在发送 multipart/form-data;
的 Content-Type
在您的代码中,您使用了 class FormUrlEncodedContent
,其说明中指出:
A container for name/value tuples encoded using application/x-www-form-urlencoded MIME type.
所以这不是正确的内容类型。
更好的匹配是 MultipartFormDataContent
因为它声明:
Provides a container for content encoded using multipart/form-data MIME type.
找到正确的 classes 我们只需要构建容器:
var dataContent = new MultipartFormDataContent();
var keyValue = new ByteArrayContent( Encoding.ASCII.GetBytes("abcd") );
dataContent.Add(keyValue, "key");
using (var client = new HttpClient())
{
// open your file
using (var fs = File.OpenRead(@"c:\path\to\audio.acc"))
{
// create StreamContent from the file
var fileValue = new StreamContent(fs);
// add the name and meta-data
dataContent.Add(fileValue, "media", "audio.acc");
HttpResponseMessage response = await client.PostAsync(
"http://yoursite.org",
dataContent);
HttpContent responseContent = response.Content;
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
Console.WriteLine(await reader.ReadToEndAsync());
}
}
}
运行 此代码显示在 Fiddler:
POST / HTTP/1.1
Content-Type: multipart/form-data; boundary="f7335f00-bc16-4518-ae7a-149491403792"
Host: yoursite.org
Content-Length: 1014
Expect: 100-continue
Connection: Keep-Alive
--f7335f00-bc16-4518-ae7a-149491403792
Content-Disposition: form-data; name=key
abcd
--f7335f00-bc16-4518-ae7a-149491403792
Content-Disposition: form-data; name=media; filename=audio.acc; filename*=utf-8''audio.acc
这更符合 curl 的跟踪输出。
我正在尝试使用 C# 中的 HTTPClient 对象将 post 请求发送到 API。 这是 CURL 命令:
curl -X POST https://zzz.zzz.zzz/yyy -F Key=abcd -F media=@"audio.aac"
我写了下面的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.IO;
using System.Net.Http.Headers;
namespace Speech2Text
{
class Program
{
static void Main(string[] args)
{
curl().Wait();
}
static async Task curl()
{
var client = new HttpClient();
//Create List of KeyValuePairs
List<KeyValuePair<string, string>> bodyProperties = new List<KeyValuePair<string, string>>();
bodyProperties.Add(new KeyValuePair<string, string>("key", "abcd"));
bodyProperties.Add(new KeyValuePair<string, string>("media", "@audio.aac"));
var dataContent = new FormUrlEncodedContent(bodyProperties.ToArray());
HttpResponseMessage response = await client.PostAsync("https://zzz.zzz.zzz/yyy", dataContent);
HttpContent responseContent = response.Content;
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
Console.WriteLine(await reader.ReadToEndAsync());
}
}
}
}
但我一直收到这个:
{"code":400,"message":"Please use [media] for the media file field name in your POST request."}
dataContect 变量是否有任何问题或其他问题?
发送 POST 时,重要的是您发送到服务器的 Content-Type 确实是服务器所期望的类型。您可以使用 curl:
中的-trace
选项轻松验证发送的内容
curl -v --trace - -X POST http://localhost -F Key=abcd -F media=@"image.txt"
当你 运行 时,你会在前几行的某个地方找到这个:
00b0: 63 6f 6e 74 69 6e 75 65 0d 0a 43 6f 6e 74 65 6e continue..Conten
00c0: 74 2d 54 79 70 65 3a 20 6d 75 6c 74 69 70 61 72 t-Type: multipar
00d0: 74 2f 66 6f 72 6d 2d 64 61 74 61 3b 20 62 6f 75 t/form-data; bou
00e0: 6e 64 61 72 79 3d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ndary=----------
00f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0100: 2d 2d 61 61 62 64 66 31 66 66 38 35 66 66 0d 0a --aabdf1ff85ff..
0110: 0d 0a ..
所以 curl 正在发送 multipart/form-data;
在您的代码中,您使用了 class FormUrlEncodedContent
,其说明中指出:
A container for name/value tuples encoded using application/x-www-form-urlencoded MIME type.
所以这不是正确的内容类型。
更好的匹配是 MultipartFormDataContent
因为它声明:
Provides a container for content encoded using multipart/form-data MIME type.
找到正确的 classes 我们只需要构建容器:
var dataContent = new MultipartFormDataContent();
var keyValue = new ByteArrayContent( Encoding.ASCII.GetBytes("abcd") );
dataContent.Add(keyValue, "key");
using (var client = new HttpClient())
{
// open your file
using (var fs = File.OpenRead(@"c:\path\to\audio.acc"))
{
// create StreamContent from the file
var fileValue = new StreamContent(fs);
// add the name and meta-data
dataContent.Add(fileValue, "media", "audio.acc");
HttpResponseMessage response = await client.PostAsync(
"http://yoursite.org",
dataContent);
HttpContent responseContent = response.Content;
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
Console.WriteLine(await reader.ReadToEndAsync());
}
}
}
运行 此代码显示在 Fiddler:
POST / HTTP/1.1
Content-Type: multipart/form-data; boundary="f7335f00-bc16-4518-ae7a-149491403792"
Host: yoursite.org
Content-Length: 1014
Expect: 100-continue
Connection: Keep-Alive
--f7335f00-bc16-4518-ae7a-149491403792
Content-Disposition: form-data; name=key
abcd
--f7335f00-bc16-4518-ae7a-149491403792
Content-Disposition: form-data; name=media; filename=audio.acc; filename*=utf-8''audio.acc
这更符合 curl 的跟踪输出。