2012-05-10 37 views
6

Làm thế nào tôi có thể phân tích cú pháp/deserialize một phản hồi MTOM/XOP mà tôi nhận được từ một dịch vụ web bằng WCF? Tôi có phản ứng trên đĩa. Tôi đã sao chép phản hồi bên dưới:Phân tích cú pháp/deserialize Dữ liệu MTOM/XOP .NET

Date: Wed, 02 May 2012 09:38:57 GMT 
Server: Microsoft-IIS/6.0 
P3P:CP="BUS CUR CONo FIN IVDo ONL OUR PHY SAMo TELo" 
X-Powered-By: ASP.NET 
X-AspNet-Version: 4.0.30319 
X-WindowsLive-Hydra: H: BLU165-ds6 V: 16.3.133.328 D: 2012-03-29T02:31:31 
X-Response-Time: 78.1245 
X-TransactionID: d491414e-46fd-47b2-82ce-e9cea9f564aa;BLU165-ds6;16.3.133.328;2012-05-02 09:38:57 UTC;78.1245 ms 
Set-Cookie: HMDST=dGVhcG90ZG9tZYtZm3GzLm1r3f+/q8+gdzrAPYmy9kJ+SmDZuFmVgk3E983xNyeoTZkkdIr6t8y3P4V+vPzmytdaqqFwtI8vBuc=; domain=.mail.services.live.com; path=/ 
Cache-Control: no-cache 
Pragma: no-cache 
Expires: -1 
Content-Type: application/xop+xml 
Content-Length: 6386 

MIME-Version: 1.0 
Content-Type: Multipart/Related;boundary=DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM; 
    type="application/xop+xml"; 
    start="<[email protected]>"; 

--DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM 
content-transfer-encoding: binary 
content-type: application/xop+xml; charset=utf-8; type="application/xop+xml" 
content-id: <[email protected]> 

<ItemOperations xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:B="HMMAIL:" xmlns:D="HMSYNC:" xmlns="ItemOperations:"><Status>1</Status><Responses><Fetch><ServerId>E631966A-9439-11E1-8E7B-00215AD9A7B8</ServerId><Status>1</Status><Message><xop:Include href="cid:[email protected]" /></Message></Fetch></Responses></ItemOperations> 
--DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM 
content-transfer-encoding: binary 
content-type: application/octet-stream 
content-id: <[email protected]> 

....Binary Content 
--DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM-- 

Bất kỳ trợ giúp nào được đánh giá cao.

+3

re: 'Phải có một lớp/phương pháp thực hiện những gì tôi đang cố gắng? 'Sẽ không hay đâu. Đáng buồn thay, MS nói rằng họ không làm file đính kèm trong việc thực hiện MTOM của họ. Không có phương thức xác định nào để truy cập 'cid' hoặc nội dung của nó. Tôi đang làm việc trên một lớp mở rộng có thể xử lý này (bằng cách lật đổ kênh và phân tích cú pháp MTOM đã trả về bằng tay). Tôi sẽ cho bạn biết nếu tôi nghĩ ra bất cứ điều gì ** chức năng **. nhưng đừng nín thở vào ** thanh lịch **. –

+0

Không bao giờ nín thở quá lâu! –

+0

@ user349026 - Bạn có thể phải giữ nó lâu hơn một chút. : (Hóa ra những gì tôi đã thực hiện là tài sản của công ty (theo luật sư) Tôi sẽ phải phát minh lại nó vào thời gian và máy tính của mình, đủ khác với bản gốc của tôi để có thể đăng nó ở đây –

Trả lời

4

Bạn có thể deserialize phản ứng bằng cách sử dụng các lớp WCF, như tôi sẽ hiển thị bên dưới. Nhưng trước khi chúng tôi tiến hành, MTOM này không hợp lệ - thông số boundary của tiêu đề Content-Type không đúng định dạng. Vì nó chứa '?' ký tự, nó cần phải được trích dẫn (xem MIME RFC, phần 5.1, định nghĩa của token).

Bây giờ, để deserialize nó, bạn cần phải mở tài liệu với một người đọc MTOM - và XmlDictionaryReader.CreateMtomReader sẽ cung cấp cho bạn chính xác điều đó. Với trình đọc đó được tạo, bạn có thể chuyển nó đến DataContractSerializer để deserialize đối tượng. Mã dưới đây cho thấy cách này có thể được thực hiện.

public class StackOverflow_10531128 
    { 
     const string MTOM = @"MIME-Version: 1.0 
Content-Type: Multipart/Related;boundary=DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM; 
    type=""application/xop+xml""; 
    start=""<[email protected]>""; 

--DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM 
content-transfer-encoding: binary 
Content-Type: application/xop+xml; charset=utf-8; type=""application/xop+xml"" 
content-id: <[email protected]> 

<ItemOperations xmlns:xop=""http://www.w3.org/2004/08/xop/include"" xmlns:B=""HMMAIL:"" xmlns:D=""HMSYNC:"" xmlns=""ItemOperations:""> 
    <Status>1</Status> 
    <Responses> 
     <Fetch> 
      <ServerId>E631966A-9439-11E1-8E7B-00215AD9A7B8</ServerId> 
      <Status>1</Status> 
      <Message><xop:Include href=""cid:[email protected]"" /></Message> 
     </Fetch> 
    </Responses> 
</ItemOperations> 
--DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM 
content-transfer-encoding: binary 
Content-Type: application/octet-stream 
content-id: <[email protected]> 

this is a binary content; it could be anything but for simplicity I'm using text 
--DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM--"; 

     [DataContract(Name = "ItemOperations", Namespace = "ItemOperations:")] 
     public class ItemOperations 
     { 
      [DataMember(Order = 1)] 
      public int Status { get; set; } 
      [DataMember(Order = 2)] 
      public Responses Responses { get; set; } 
     } 

     [CollectionDataContract(Name = "Responses", Namespace = "ItemOperations:", ItemName = "Fetch")] 
     public class Responses : List<Fetch> 
     { 
     } 

     [DataContract(Name = "Fetch", Namespace = "ItemOperations:")] 
     public class Fetch 
     { 
      [DataMember(Order = 1)] 
      public Guid ServerId { get; set; } 
      [DataMember(Order = 2)] 
      public int Status { get; set; } 
      [DataMember(Order = 3)] 
      public byte[] Message { get; set; } 
     } 

     public static void Test() 
     { 
      MemoryStream ms; 
      ItemOperations obj; 
      DataContractSerializer dcs = new DataContractSerializer(typeof(ItemOperations)); 

      string fixedMtom = MTOM.Replace(
       "Multipart/Related;boundary=DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM;", 
       "Multipart/Related;boundary=\"DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM\";"); 
      ms = new MemoryStream(Encoding.UTF8.GetBytes(fixedMtom)); 
      XmlDictionaryReader reader = XmlDictionaryReader.CreateMtomReader(ms, Encoding.UTF8, XmlDictionaryReaderQuotas.Max); 
      obj = (ItemOperations)dcs.ReadObject(reader); 
      Console.WriteLine(obj.Status); 
      Console.WriteLine(obj.Responses.Count); 
      foreach (var resp in obj.Responses) 
      { 
       Console.WriteLine(" {0}", resp.ServerId); 
       Console.WriteLine(" {0}", resp.Status); 
       Console.WriteLine(" {0}", string.Join(" ", resp.Message.Select(b => string.Format("{0:X2}", (int)b)))); 
      } 
     } 
    } 
+0

. có một dòng nhị phân của một hình ảnh, và nó được chuyển đổi thành một chuỗi như trong ví dụ của bạn, nó có thể làm hỏng luồng hay không? – Victor

+0

Đây là một ví dụ đơn giản cho thấy cách đọc tài liệu MTOM bằng cách sử dụng các lớp WCF, và để làm cho nó hoàn thành và tự chứa Tôi đã mã hóa cứng "tài liệu" MTOM dưới dạng một chuỗi trong tệp. Điều thường xảy ra là tài liệu sẽ được đọc từ một số nguồn bên ngoài (tệp, mạng, v.v.) và các byte sẽ được mã hóa đúng cách (và sẽ được đọc chính xác bởi đầu đọc MTOM). – carlosfigueira

Các vấn đề liên quan