将 curl --form 转换为 C#
Convert curl --form to C#
我正在使用外部 api 并想使用 multipart/form-data 上传文件。 curl 中的工作解决方案是:curl --form file=@./fileName.mp4 "http://page.com"
根据https://curl.olsh.me/。我正在寻找的代码是:
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "http://page.com/"))
{
var multipartContent = new MultipartFormDataContent();
multipartContent.Add(new ByteArrayContent(File.ReadAllBytes("./fileName.mp4")), "file", Path.GetFileName("./fileName.mp4"));
request.Content = multipartContent;
var response = await httpClient.SendAsync(request);
}
}
然而它不起作用。 headers 和文件不同,所以我遇到了错误。
我写的代码和'works',但是附件无效,因为编码字节到字符串不正确。
var webClient = new HttpClient();
webClient.DefaultRequestHeaders.ExpectContinue = true;
string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
var fileData = Encoding.ASCII.GetString(System.IO.File.ReadAllBytes(pathToFile));
var package = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n{3}\r\n--{0}--\r\n", boundary, "fileName", "application/octet-stream", fileData);
var content = new StringContent(package);
content.Headers.Remove("Content-Type");
content.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
content.Headers.Remove("Content-Length");
content.Headers.Add("Content-Length", package.Length.ToString());
await webClient.PostAsync(address, content);
编辑:
来自 curl 请求的 headers:
POST http://page.com/ HTTP/1.1
Host: page.com
User-Agent: curl/7.55.1
Accept: */*
Connection: Keep-Alive
Content-Length: 1703578
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------1a538744c5619c1e
--------------------------1a538744c5619c1e
Content-Disposition: form-data; name="file"; filename="cst.mp4"
Content-Type: application/octet-stream
第一个示例代码中的 headers:
POST http://page.com/ HTTP/1.1
Content-Type: multipart/form-data; boundary="735b20d4-4de4-46fb-8293-2c2e996ce180"
Content-Length: 1703552
Host: page.com
--735b20d4-4de4-46fb-8293-2c2e996ce180
Content-Disposition: form-data; name=file; filename=cst.mp4; filename*=utf-8''cst.mp4
我认为文件大小差异在这里是一个转移注意力的问题。
Web 服务器的常见做法是拒绝未指定用户代理的请求。尝试添加用户代理(甚至欺骗 curl 代理),如下所示:
webClient.DefaultRequestHeaders.Add("User-Agent", "curl/7.55.1");
第一个代码的问题是边界、文件headers 和输出headers 不同。我必须添加两个 Content-Type headers - 一个到我的文件,一个到输出。我无法添加正确的 headers 并删除错误的,因为我试图将 headers 添加到 multipart 而不是 multipart 内容。
如果您想将 header 添加到您的多部分内容中,您需要在 HttpContent
上进行。
工作解决方案是:
string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), address))
{
httpClient.DefaultRequestHeaders.Add("User-Agent", userAgentName);
httpClient.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
httpClient.DefaultRequestHeaders.ExpectContinue = true;
var multipartContent = new MultipartFormDataContent(boundary);
multipartContent.Headers.Remove("Content-Type");
multipartContent.Headers.Add("Content-Type", "multipart/form-data; boundary="+boundary);
var bcd = new ByteArrayContent(System.IO.File.ReadAllBytes(path));
bcd.Headers.Clear();
bcd.Headers.Add("Content-Disposition", "form-data; name=\"file\"; filename=\""+fileName+"\"");
bcd.Headers.Add("Content-Type", "application/octet-stream");
multipartContent.Add(bcd, "file", fileName);
request.Content = multipartContent;
var response = await httpClient.SendAsync(request);
}
}
现在 curl 和 HttpClient 的 headers 几乎相同(缺少 Accept header,但我不需要它)。
我正在使用外部 api 并想使用 multipart/form-data 上传文件。 curl 中的工作解决方案是:curl --form file=@./fileName.mp4 "http://page.com"
根据https://curl.olsh.me/。我正在寻找的代码是:
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "http://page.com/"))
{
var multipartContent = new MultipartFormDataContent();
multipartContent.Add(new ByteArrayContent(File.ReadAllBytes("./fileName.mp4")), "file", Path.GetFileName("./fileName.mp4"));
request.Content = multipartContent;
var response = await httpClient.SendAsync(request);
}
}
然而它不起作用。 headers 和文件不同,所以我遇到了错误。
我写的代码和'works',但是附件无效,因为编码字节到字符串不正确。
var webClient = new HttpClient();
webClient.DefaultRequestHeaders.ExpectContinue = true;
string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
var fileData = Encoding.ASCII.GetString(System.IO.File.ReadAllBytes(pathToFile));
var package = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n{3}\r\n--{0}--\r\n", boundary, "fileName", "application/octet-stream", fileData);
var content = new StringContent(package);
content.Headers.Remove("Content-Type");
content.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
content.Headers.Remove("Content-Length");
content.Headers.Add("Content-Length", package.Length.ToString());
await webClient.PostAsync(address, content);
编辑: 来自 curl 请求的 headers:
POST http://page.com/ HTTP/1.1
Host: page.com
User-Agent: curl/7.55.1
Accept: */*
Connection: Keep-Alive
Content-Length: 1703578
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------1a538744c5619c1e
--------------------------1a538744c5619c1e
Content-Disposition: form-data; name="file"; filename="cst.mp4"
Content-Type: application/octet-stream
第一个示例代码中的 headers:
POST http://page.com/ HTTP/1.1
Content-Type: multipart/form-data; boundary="735b20d4-4de4-46fb-8293-2c2e996ce180"
Content-Length: 1703552
Host: page.com
--735b20d4-4de4-46fb-8293-2c2e996ce180
Content-Disposition: form-data; name=file; filename=cst.mp4; filename*=utf-8''cst.mp4
我认为文件大小差异在这里是一个转移注意力的问题。
Web 服务器的常见做法是拒绝未指定用户代理的请求。尝试添加用户代理(甚至欺骗 curl 代理),如下所示:
webClient.DefaultRequestHeaders.Add("User-Agent", "curl/7.55.1");
第一个代码的问题是边界、文件headers 和输出headers 不同。我必须添加两个 Content-Type headers - 一个到我的文件,一个到输出。我无法添加正确的 headers 并删除错误的,因为我试图将 headers 添加到 multipart 而不是 multipart 内容。
如果您想将 header 添加到您的多部分内容中,您需要在 HttpContent
上进行。
工作解决方案是:
string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), address))
{
httpClient.DefaultRequestHeaders.Add("User-Agent", userAgentName);
httpClient.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
httpClient.DefaultRequestHeaders.ExpectContinue = true;
var multipartContent = new MultipartFormDataContent(boundary);
multipartContent.Headers.Remove("Content-Type");
multipartContent.Headers.Add("Content-Type", "multipart/form-data; boundary="+boundary);
var bcd = new ByteArrayContent(System.IO.File.ReadAllBytes(path));
bcd.Headers.Clear();
bcd.Headers.Add("Content-Disposition", "form-data; name=\"file\"; filename=\""+fileName+"\"");
bcd.Headers.Add("Content-Type", "application/octet-stream");
multipartContent.Add(bcd, "file", fileName);
request.Content = multipartContent;
var response = await httpClient.SendAsync(request);
}
}
现在 curl 和 HttpClient 的 headers 几乎相同(缺少 Accept header,但我不需要它)。