2012-05-10 25 views
6

Come posso analizzare/deserializzare una risposta MTOM/XOP che ottengo da un servizio Web che utilizza WCF? Ho la risposta su disco. Ho copiato la risposta qui sotto:Analizza/deserializza dati 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-- 

Qualsiasi aiuto è molto apprezzato.

+3

re: 'Ci deve essere una classe/metodo che fa quello che sto provando?' Non sarebbe bello. Purtroppo, MS dichiara di non fare allegati nella loro implementazione MTOM. Non esiste un metodo definito per accedere a 'cid' o ai suoi contenuti. Sto lavorando su una classe di estensione in grado di gestirlo (sovvertendo il canale e analizzando a mano il ritorno MTOM). Ti farò sapere se trovo qualcosa ** funzionale **. ma non trattenere il respiro su ** elegante **. –

+0

Non trattenere mai il respiro così a lungo! –

+0

@ user349026 - Potrebbe essere necessario tenerlo un po 'più a lungo. :(venuto fuori quello che ho implementato è proprietà dell'azienda (secondo gli avvocati). Dovrò reinventarlo il mio tempo e computer, sufficientemente diverso dal mio originale per essere in grado di postare qui. –

risposta

4

È possibile deserializzare la risposta utilizzando le classi WCF, come ti faccio vedere qui di seguito. Ma prima di procedere, questo MTOM non è valido - il parametro boundary dell'intestazione Content-Type non è valido. Dal momento che contiene il '?' carattere, ha bisogno di essere citato (sguardo al MIME RFC, paragrafo 5.1, definizione di token).

Ora, per deserializzare, è necessario aprire il documento con un lettore MTOM - e XmlDictionaryReader.CreateMtomReader ti darà esattamente quello. Con quel lettore creato, puoi passarlo allo DataContractSerializer per deserializzare l'oggetto. Il codice sotto mostra come questo può essere fatto.

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

se il MTOM ha un flusso binario di un'immagine, ed è convertito in una stringa come nel tuo esempio, potrebbe che danneggiare il flusso o no? – Victor

+0

Questo è un semplice esempio che mostra come leggere il documento MTOM utilizzando le classi WCF, e per renderla completa e self-contained I hard-coded il "documento" MTOM come una stringa nel file. Cosa accadrebbe normalmente è il documento sarebbe stato letto da una fonte esterna (file, rete, ecc), e il byte sarebbe correttamente codificato (e verrebbe letto correttamente dal lettore MTOM). – carlosfigueira

Problemi correlati