2013-08-28 20 views
2

我有一個混亂的情況,我希望有人可以提供解決方案。所以請在我提供一些背景的時候和我一起裸照。基本上我使用JavaScript與第三方服務進行通信。作爲身份驗證過程的一部分,他們需要郵件消息的「multipart/form」主體,包括要在md5中加密的圖像,將其添加到包含日期和其他一些字符串的字符串中,然後運行HMAc/SHA1運行在上面。所以最後他們有多部分主體,日期和認證哈希,以便驗證並讀取圖像。HttpClient設置與內容類型的邊界

這適用於除WindowsPhone之外的所有移動設備。(我知道,IE的問題......誰會想到?)。他們的httpwebrequest不包括'日期'標題..所以沒有認證。這意味着我必須爲Windows Phone本地化並使用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呃ROR。 任何幫助表示讚賞。

回答

3

與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_"; 
+0

謝謝,我實際上剛剛找到了同樣的東西content.headers.add,並得到它的工作。不幸的是,我不能使用httpwebrequest解決方案,因爲從我讀過的內容來看,這是沒有爲wp8填充日期標題的部分。謝謝。 – user2548513

+1

我不熟悉wp8 dev。 httpwebrequest可以添加自定義頭文件myHttpWebRequest.Headers.Add(「name」,「value」); – user553838

+0

是的,據我瞭解,這是特定於WP8而不是一般的C#,在WindowsPhone8版本的HttpWebRequest中沒有'Date'屬性。所有其他標題似乎工作正常,但'日期'標題從未包含在您的請求中,這就是爲什麼我必須使用HttpClient。 – user2548513

1

我們通過手動清除並重新添加的內容類型,而不驗證 似乎解決了這個的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中,如果有什麼差別)

0

我在這裏發佈我的代碼,也許這將幫助別人掙扎像我一樣,對我來說,這部作品並上傳文件到我的帳戶(不是銀行,而是安全的雲文件產品)

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.GetResponseWithTimeout()) 
      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; 
    }