2014-07-18 15 views
5

tôi nhận được một multipart/mixed (với một đối tượng JSON và một tập tin) như thế này, như phản ứng khi tôi gọi một dịch vụ web:đọc multipart/mixed trong C# (.NET 4.0)

"--Boundary_9_15033478_1405613164044\r\n 

Content-Type: application/json 
\r\n\r\n{\"docId\":9007492,\"protId\":200,\"protNum\":\"0002084B14\",\"protDate\":\"Wed Jul 16 00:00:00 EEST 2014\",\"categoryId\":1000,\"desc\":\"ѥⷞ ��ƣ䲜��",\"linkNum\":\"ư1\\/00005545\",\"flag1\":\"\",\"flag2\":\"\",\"flag3\":\"\",\"flag4\":\"\",\"stsId\":1,\"stsDesc\":\"WS04: Check Layer I - OK\",\"wsDataList\":[],\"fileName\":\"WsTestToolkitMain.jpg\"}\r\n--Boundary_9_15033478_1405613164044\r\n 

Content-Type: application/octet-stream 
\r\n\r\n????\0JFIF\0\0`\0`\0\0??\0C\0\a\a\a\a\a\a\b\t\v\t\b\b\n\b\a\a\n\r\n\n\v\f\f\f 
... 
... 
... 
??\n?$??\0???????\r\n--Boundary_9_15033478_1405613164044--\r\n" 

Cách Tôi nhận được nó là bằng cách nhận được một dòng phản ứng (của HttpWebRequest) và sau đó giải mã nó với UTF-8. Điều này cho tôi chuỗi ở trên. Câu hỏi là làm cách nào để nhận được JSON và (quan trọng hơn) lưu tệp?

tôi đã cố gắng thay đổi (vì họ là dành cho multipart/form-data không multipart/mixed) thisthis nhưng tôi không thể nhận được các tập tin, có lẽ vì nó Content-Type là application/octet-stream. Đây là những gì không làm việc, tập tin dường như nó đã bị hư hỏng/hư hỏng trong các cửa sổ:

// Read the stream into a byte array 
byte[] data = ToByteArray(stream);//Source 
string content = encoding.GetString(data); 
int contentLength = content.Length;//Length 
byte[] fileData = new byte[contentLength];//Destination 
Buffer.BlockCopy(data, startIndex, fileData, 0, contentLength); 
this.FileContents = fileData; 
File.WriteAllBytes("G:\\" + parser.Filename, parser.FileContents); 

CẬP NHẬT: (! Thanks) Tiếp theo câu trả lời bởi Anton Tykhyy nhưng tôi nhận được một lỗi khi

var multipart = await content.ReadAsMultipartAsync() ; 

Ví dụ 'HttpContent' không hợp lệ được cung cấp. Nó không có giá trị tiêu đề kiểu nội dung. Các phiên bản 'HttpContent' phải có tiêu đề kiểu nội dung bắt đầu bằng 'multipart /'.

Tôi cố gắng để thêm dòng này trước khi

content.Headers.Add("Content-Type", "multipart/mixed"); 

nhưng bây giờ tôi nhận được một lỗi (mà tôi không thực sự hiểu quá)

không hợp lệ 'HttpContent' dụ cung cấp. Nó không có tiêu đề kiểu nội dung 'multipart' với thông số 'ranh giới'.

UPDATE 2: Tìm thấy nó, tôi chỉ phải làm điều này:

var content = new StreamContent(httpResponse.GetResponseStream()); 
    content.Headers.Add("Content-Type", httpResponse.ContentType); 

Trả lời

4

Sử dụng ReadAsMultipartAsync trong System.Net.Http.Formatting assembly, dọc theo dòng của

var content = new StreamContent (stream) ; 
var multipart = await content.ReadAsMultipartAsync() ; 
foreach (var part in multipart) 
{ 
    if (part.Headers.ContentType.MediaType == "application/json") 
    { 
     // deserialize via stream e.g. part.ReadAsStreamAsync() or via string 
     // using part.ReadAsStringAsync() to avoid charset grief 
    } 
    else 
    using (var file = File.Create (parser.Filename)) 
     await part.CopyToAsync (file) ; 
} 

này nên để có được bạn đã bắt đầu.

1

tôi quản lý để giải quyết vấn đề của tôi (đọc nhiều phần dữ liệu đó là), nhưng đã phải di chuyển đến NET 4.5, nếu có ai biết những thay đổi để làm việc trong .NET 4.0 (bằng cách thay thế "chờ đợi" và "không đồng bộ" với cái gì khác tôi đoán) Tôi rất muốn biết. Vì vậy, đó là những gì tôi đã làm.

static void Main(string[] args) 
    { 

      //some code here... 

      // POST the request 
      var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 
      Console.Write(httpResponse.GetResponseStream()); 
      readMultipart(httpResponse).Wait(); 
    } 

    async static Task readMultipart(HttpWebResponse httpResponse) 
    { 
     var content = new StreamContent(httpResponse.GetResponseStream()); 
     content.Headers.Add("Content-Type", httpResponse.ContentType); 
     var multipart = await content.ReadAsMultipartAsync(); 
     String filename = ""; 
     String json = await multipart.Contents[0].ReadAsStringAsync(); 
     JObject o = JObject.Parse(json); 
     filename = o["fileName"].ToString(); 
     using (var file = File.Create("C:\\testWS\\" + filename)) 
      await multipart.Contents[1].CopyToAsync(file); 
    } 
+1

Cách tiếp cận đơn giản nhất là thay thế 'đang chờ' bằng '.Result', mặc dù điều này chặn luồng. Bạn có thể thử nhắm mục tiêu .NET 4.0 với trình biên dịch 4.5, vì trong khi mã tương đương với trình biên dịch tạo ra 'async/await' có thể được viết bằng tay bằng cách sử dụng '.ContinueWith', nó phức tạp và phức tạp (đó là lý do tại sao' async/await' là thêm vào trình biên dịch). –