C# HttpClient设置内容类型为的边界
我正在使用javascript与第三方服务通信。作为身份验证过程的一部分,他们需要post消息的“multipart/form”主体,包括一个要在md5中加密的图像,它被添加到一个包含日期和其他一些内容的字符串中,然后在该字符串上运行HMAc/SHA1。因此,最终他们拥有多部分主体、日期和身份验证哈希,以便进行身份验证,然后读取图像 这适用于除windowsPhone以外的所有移动设备。。(我知道,IE有问题……谁会想到?)。他们的httpwebrequest不包含“日期”标题。。所以没有身份验证。这意味着我必须使用windows phone的本机版本,并在C#中使用新发布的httpclient代码。现在我是个笨蛋,所以这可能是最简单的解决办法。我已经通过将几乎所有内容传递给c#并使用c#来完成post来实现身份验证,但是他们无法读取正文,因为我发现发送边界的唯一方法是将内容定义为multipartformDatacontent,然后以这种方式发送内容会改变正文,因此身份验证失败 我的javascript类似于:C# HttpClient设置内容类型为的边界,c#,javascript,httpclient,content-type,boundary,C#,Javascript,Httpclient,Content Type,Boundary,我正在使用javascript与第三方服务通信。作为身份验证过程的一部分,他们需要post消息的“multipart/form”主体,包括一个要在md5中加密的图像,它被添加到一个包含日期和其他一些内容的字符串中,然后在该字符串上运行HMAc/SHA1。因此,最终他们拥有多部分主体、日期和身份验证哈希,以便进行身份验证,然后读取图像 这适用于除windowsPhone以外的所有移动设备。。(我知道,IE有问题……谁会想到?)。他们的httpwebrequest不包含“日期”标题。。所以没有身份验
var boundary = "------------ThIs_Is_tHe_bouNdaRY_";
var part1Array = [];
var part1 = "--"+boundary + "\r\n"+
"Content-Disposition: form-data; name=\"image\"\r\n"+
"Content-Type: image/jpg\r\n"+
"\r\n";
var part3Array = [];
var part3 = "\r\n" + boundary +"--";
for(var p1=0; p1<part1.length; p1++){
part1Array.push(part1.charCodeAt(p1));
}
for(var p3=0; p3<part3.length; p3++){
part3Array.push(part3.charCodeAt(p3));
}
var bodyContent = part1Array.concat(imageArray,part3Array);
//hash this
var authMessage = bodyContentHash +"\n"+ contentType +"\n"+ todayString +"\n"+ pathandstuff;
// -hmac -sha1 -base64
这很管用。。正文内容和标题都是正确的。。除内容类型标题外的所有内容类型标题应为:
request.Content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data, boundary=------------ThIs_Is_tHe_bouNdaRY_");
但这会引发System.FormatException错误。与HttpClient一起使用
request.Content.Headers.Add("ContentType", "multipart/form-data, boundary=------------ThIs_Is_tHe_bouNdaRY_");
您可以使用HttpWebRequest
myHttpWebRequest.Date = DateTime.Now;
myHttpWebRequest.ContentType = "multipart/form-data, boundary=------------ThIs_Is_tHe_bouNdaRY_";
我们通过手动清除并重新添加内容类型(无需验证)来解决此问题 MediaTypeHeaderValue()类似乎不喜欢边界标记 而不是使用:
content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data; boundary=----FLICKR_MIME_20140415120129--");
我们做了以下工作:
content.Headers.Remove("Content-Type");
content.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=----FLICKR_MIME_20140415120129--");
一旦我们做了这个改变,一切都正常工作了
(请注意,如果这有什么不同的话,这是在WinRT上的)我在这里发布了我的代码,也许这会帮助其他像我一样挣扎的人,在我的情况下,这会起作用,并将文件上传到我的帐户(不是银行,而是安全的云文件产品)
谢谢,事实上我刚刚找到了同样的东西content.headers.add并使它工作了。不幸的是,我不能使用httpwebrequest解决方案,因为从我所读到的内容来看,这是不填充wp8的日期头的部分。谢谢。我不熟悉wp8开发。httpwebrequest可以添加自定义头myHttpWebRequest.Headers.add(“名称”、“值”);是的,据我所知,这是特定于WP8而不是c的。一般来说,WindowsPhone8版本的HttpWebRequest中没有“Date”属性。所有其他标题似乎都可以正常工作,但“日期”标题从未包含在您的请求中,这就是我必须使用HttpClient的原因。--HttpClient request.Content.headers解决方案非常有效:)再次感谢。开箱即用,因此我不得不竖起大拇指(:,添加函数GetResponseWithTimeout或编辑它
content.Headers.Remove("Content-Type");
content.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=----FLICKR_MIME_20140415120129--");
public string UploadFile(string endpointUrl, string filePath, string accessToken)
{
FileStream fs = null;
Stream rs = null;
string result = "";
try
{
string uploadFileName = System.IO.Path.GetFileName(filePath);
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
var request = (HttpWebRequest)WebRequest.Create(endpointUrl);
request.Method = WebRequestMethods.Http.Post;
request.AllowWriteStreamBuffering = false;
request.SendChunked = true;
String CRLF = "\r\n"; // Line separator required by multipart/form-data.
long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
string boundary = timestamp.ToString("x");
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Headers.Add("Authorization", "Bearer " + accessToken);
long bytesAvailable = fs.Length;
long maxBufferSize = 1 * 1024 * 1024;
rs = request.GetRequestStream();
byte[] buffer = new byte[50];
int read = 0;
byte[] buf = Encoding.UTF8.GetBytes("--" + boundary + CRLF);
rs.Write(buf, 0, buf.Length);
buf = Encoding.UTF8.GetBytes("Content-Disposition: form-data; name=\"body\"; filename=\"" + uploadFileName + "\"" + CRLF);
rs.Write(buf, 0,buf.Length);
buf = Encoding.UTF8.GetBytes("Content-Type: application/octet-stream;" + CRLF);
rs.Write(buf, 0, buf.Length);
buf = Encoding.UTF8.GetBytes(CRLF);
//writer.append("Content-Type: application/octet-stream;").append(CRLF);
rs.Write(buf, 0, buf.Length);
rs.Flush();
long bufferSize = Math.Min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
while ((read = fs.Read(buffer, 0, buffer.Length)) != 0)
{
rs.Write(buffer, 0, read);
}
buf = Encoding.UTF8.GetBytes(CRLF);
rs.Write(buf, 0, buf.Length);
rs.Flush();
// End of multipart/form-data.
buffer = Encoding.UTF8.GetBytes("--" + boundary + "--" + CRLF);
rs.Write(buffer, 0, buffer.Length);
using (var response = request.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var reader = new StreamReader(responseStream))
{
result = reader.ReadToEnd();
}
}
catch (Exception e)
{
result = e.InnerException != null ? e.InnerException.Message : e.Message;
}
return result;
}