[英]HttpClient setting boundary with content-type
我正在使用javascript與第三方服務進行通信。 作為其身份驗證過程的一部分,他們需要發布消息的“multipart / form”主體,包括要在md5中加密的圖像,這將添加到包含日期和其他一些內容的字符串中,然后再運行HMAc / SHA1在上面。 所以最后他們有多部分主體,日期和身份驗證哈希,以便進行身份驗證,然后讀取圖像。
這適用於所有移動設備,除了windowsPhone ..(我知道,IE的問題......誰會想到?)。 他們的httpwebrequest不包含'Date'標題..所以沒有身份驗證。 這意味着我必須使用Windows手機本機並在C#中使用新發布的httpclient代碼。 現在我是一個C#noob,所以這可能是簡單的解決方案。 我已經通過將所有內容傳遞給c#以及使用c#進行帖子來獲得身份驗證,但是他們無法讀取正文,因為我發現發送邊界的唯一方法是將內容定義為multipartformDatacontent並發送內容方式改變了身體,因此身份驗證失敗了。
我的javascript是這樣的:
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
而c#是:
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, path);
request.Headers.Date = DateTime.ParseExact(todaydate, "ddd',' dd MMM yyyy HH:mm:ss 'GMT'", new CultureInfo("en-US"), DateTimeStyles.AssumeUniversal);
request.Headers.Add("Accept", "application/json; charset=utf-8");
request.Headers.Add("Authorization", auth);
byte[] body = Convert.FromBase64String(bodyData);
request.Content = new ByteArrayContent(body);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
request.Content.Headers.Add("boundary", "------------ThIs_Is_tHe_bouNdaRY_");
HttpResponseMessage response = client.SendAsync(request).Result;
string resultCode = response.StatusCode.ToString();
string responseBodyAsText = await response.Content.ReadAsStringAsync();
這幾乎是有效的..正文內容是正確的標題..所有除了內容類型標題應該是:
request.Content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data, boundary=------------ThIs_Is_tHe_bouNdaRY_");
除了這會拋出System.FormatException錯誤。
我們通過手動清除和重新添加內容類型來解決這個問題,而無需驗證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上)
使用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_";
我在這里發布我的代碼,也許這會幫助其他人像我一樣苦苦掙扎,在我的情況下,這可以工作並將文件上傳到我的帳戶(不是銀行業務,而是安全的雲文件產品)
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.