【发布时间】:2020-11-03 22:27:46
【问题描述】:
我无法将只有键/值对(无文件)的 MultipartFormDataContent 发布请求发送到特定 API。
我试过了:
- FormUrlEncodedContent 键值对
- MultipartFormDataContent.Add(new StringContent(value), "nameofvalue");
- 查看了示例,唯一可行的解决方案是使用 Web 请求。 Web请求是老客户端,我 更喜欢使用优雅 -> HttpClient。
附加代码示例,该示例使用 Web 请求,我无法用 HTTP 客户端替换:
public static class FormUpload
{
private static readonly Encoding encoding = Encoding.UTF8;
public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, Dictionary<string, object> postParameters)
{
var formDataBoundary = $"----------{Guid.NewGuid():N}";
var contentType = "multipart/form-data; boundary=" + formDataBoundary;
var formData = GetMultipartFormData(postParameters, formDataBoundary);
return PostForm(postUrl, userAgent, contentType, formData);
}
private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData)
{
var request = WebRequest.Create(postUrl) as HttpWebRequest;
if (request == null)
{
throw new NullReferenceException("request is not a http request");
}
request.Method = "POST";
request.ContentType = contentType;
request.UserAgent = userAgent;
request.CookieContainer = new CookieContainer();
request.ContentLength = formData.Length;
using var requestStream = request.GetRequestStream())
requestStream.Write(formData, 0, formData.Length);
requestStream.Close();
return request.GetResponse() as HttpWebResponse;
}
private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
{
using var formDataStream = new MemoryStream();
var needsClrf = false;
foreach (var param in postParameters)
{
// Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
// Skip it on the first parameter, add it to subsequent parameters.
if (needsClrf)
formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));
needsClrf = true;
var postData = $"--{boundary}\r\nContent-Disposition: form-data; name=\"{param.Key}\"\r\n\r\n{param.Value}";
formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
}
// Add the end of the request. Start with a newline
var footer = "\r\n--" + boundary + "--\r\n";
formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));
// Dump the Stream into a byte[]
formDataStream.Position = 0;
var formData = new byte[formDataStream.Length];
formDataStream.Read(formData, 0, formData.Length);
return formData;
}
}
【问题讨论】:
-
在邮递员中它只是一个简单的表单数据请求,它很容易工作,我无法在 c# 上重现它。截图示例:i.ibb.co/3RsYqyJ/postman.png
标签: .net .net-core httpclient rest