2012-05-10 2 views
6

Wie kann ich eine /XOP Antwort, die ich von einem Webdienst mit WCF erhalte, analysieren/deserialisieren? Ich habe die Antwort auf der Festplatte. Ich habe die Antwort unten kopiert:MTOM/XOP-Daten analysieren/deserialisieren .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: <1.[email protected]> 

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

Jede Hilfe ist sehr geschätzt.

+3

re: 'Es muss eine Klasse/Methode geben, die das tut, was ich versuche?' Wäre das nicht nett? Leider sagt MS, dass sie in ihrer MTOM-Implementierung keine Anhänge machen. Es gibt keine definierte Methode, um auf die 'cid' oder deren Inhalt zuzugreifen. Ich arbeite an einer Erweiterungsklasse, die damit umgehen kann (indem Sie den Kanal untergraben und den zurückkehrenden MTOM von Hand analysieren). Ich werde dich wissen lassen, wenn ich mir etwas Funktionelles einfallen lasse. aber halte nicht den Atem an ** elegant **. –

+0

Nie wird den Atem so lange halten! –

+0

@ user349026 - Sie müssen es vielleicht etwas länger halten. :(Stellt sich heraus, was ich implementiert habe, ist das Firmeneigentum (laut den Anwälten). Ich werde es auf meine eigene Zeit und Computer neu erfinden müssen, ausreichend anders als mein Original, um es hier zu veröffentlichen. –

Antwort

4

Sie können die Antwort mit den WCF-Klassen deserialisieren, wie ich weiter unten zeigen werde. Aber bevor wir fortfahren, ist dieser MTOM ungültig - der Parameter boundary des Headers ist fehlerhaft. Da es das '?' Zeichen, muss es zitiert werden (siehe MIME RFC, Abschnitt 5.1, Definition von token).

Nun, um es zu deserialisieren, müssen Sie das Dokument mit einem MTOM-Leser öffnen - und XmlDictionaryReader.CreateMtomReader wird Ihnen genau das geben. Wenn dieser Leser erstellt wurde, können Sie ihn an die DataContractSerializer übergeben, um das Objekt zu deserialisieren. Der folgende Code zeigt, wie dies getan werden kann.

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

wenn der MTOM hat einen binären Stream eines Bildes, und es wird in eine Zeichenfolge wie in Ihrem Beispiel konvertiert, würde das den Stream oder nicht korrumpieren? – Victor

+0

Dies ist ein einfaches Beispiel zeigt, wie das MTOM-Dokument mit den WCF-Klassen zu lesen, und um es abzuschließen und in sich abgeschlossen Ich habe das MTOM- "Dokument" als eine Zeichenfolge in der Datei fest codiert. Was normalerweise passieren würde, wäre, dass das Dokument von einer externen Quelle (Datei, Netzwerk usw.) gelesen würde und die Bytes korrekt codiert wären (und würde vom MTOM-Leser korrekt gelesen werden). – carlosfigueira