2013-08-28 7 views
2

나는 누군가가 해결책을 제시 할 수 있기를 바랄 지경이다. 그러니 내가 약간의 배경을 제공하면서 나랑 벗겨주세요. 기본적으로 제 3 자 서비스와 통신하기 위해 자바 스크립트를 사용하고 있습니다. 인증 프로세스의 일부로, md5에서 암호화 될 이미지를 포함하여 게시 메시지의 "multipart/form"본문이 필요합니다. 이것은 날짜와 몇 가지 다른 것들을 포함하는 문자열에 추가 된 다음 HMAc/SHA1이 실행됩니다 그 위에. 결국 그들은 다중 부분 본문, 날짜 및 인증 해시를 사용하여 이미지를 인증하고 읽습니다.콘텐츠 유형이있는 HttpClient 설정 경계

WindowsPhone ..을 제외한 모든 모바일 장치에서 정상적으로 작동합니다. (IE에서 문제가 발생했습니다 ... 누가 생각했을까요?). 그들의 httpwebrequest는 '날짜'헤더를 포함하지 않으므로 인증이 없습니다. 이것은 내가 Windows 전화에 대한 기본 가서 C#에서 새로 릴리스 된 httpclient 코드를 사용해야한다는 것을 의미합니다. 이제는 C# noob이므로 쉬운 해결책이있는 곳입니다. 나는 거의 모든 것을 C#에 전달하고 C#을 사용하여 게시물을 작성함으로써 작동하도록 인증을 받았지만 경계를 전송하는 유일한 방법은 multipartformDatacontent로 컨텐츠를 정의 할 때 컨텐츠를 전송하기 때문에 본문을 읽을 수 없습니다. 방법은 본문을 변경하여 인증이 실패합니다. 모든 콘텐츠를 제외하고 .. 헤더가로

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(); 

이 꽤 많은 작품 .. 본문 내용이 올바른지 :

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#을은 다음과 같습니다

내 자바 스크립트는 무언가 같이가 Type 헤더되어야한다 :

이것은 System.FormatException 어를 발생하는 것을 제외
request.Content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data, boundary=------------ThIs_Is_tHe_bouNdaRY_"); 

너. 도움을 청하니 . HttpClient를

request.Content.Headers.Add("ContentType", "multipart/form-data, boundary=------------ThIs_Is_tHe_bouNdaRY_"); 

답변

3

사용할 수 HttpWebRequest를

myHttpWebRequest.Date = DateTime.Now; 
myHttpWebRequest.ContentType = "multipart/form-data, boundary=------------ThIs_Is_tHe_bouNdaRY_"; 
+0

덕분에, 사실은 그냥 같은 일이 content.headers.add을 발견하고 작업을 얻었다. 불행히도 내가 읽었던 부분에서 wp8에 대한 Date 헤더를 채우지 않는 부분이기 때문에 httpwebrequest 솔루션을 사용할 수 없습니다. 감사. – user2548513

+1

나는 wp8 dev에 익숙하지 않다. httpwebrequest는 사용자 정의 헤더 myHttpWebRequest.Headers.Add ("name", "value")를 추가 할 수 있습니다. – user553838

+0

예, WP8에 일반적으로 적용되는 것이 아니라 일반적으로 HttpWebRequest의 WindowsPhone8 버전에는 'Date'속성이 없습니다. 다른 모든 헤더는 정상적으로 작동하지만 'Date'헤더가 요청에 포함되지 않으므로 HttpClient를 사용해야했습니다. – user2548513

1

우리는 수동으로 삭제하고 검증 없이 콘텐츠 형식을 다시 추가 보인다하여이 문제를 해결하는 '이 MediaTypeHeaderValue() 클래스 아무튼 경계 태그처럼. 사용하는 대신

:

content.Headers.Remove("Content-Type"); 
content.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=----FLICKR_MIME_20140415120129--"); 

우리가 모두 제대로 작동이 변경 한 후 :

content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data; boundary=----FLICKR_MIME_20140415120129--"); 

우리는 다음과 같은했다.

이 작품 내 경우에, 어쩌면 이것은 다른 사람이 내가 그랬던 것처럼 어려움을 겪고 도움이 될 것입니다, 여기에 내 코드를 게시

0

(즉, 어떤 차이가있는 경우이 WinRT에 유의) 내 계정에 파일을 업로드 (안 은행하지만 안전한 클라우드 파일 제품)

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; 
    }