question

JulioBello-4525 avatar image
0 Votes"
JulioBello-4525 asked JulioBello-4525 answered

Error Deserializing SOAP Envelope

Hi, Everybody!

I have spent hours trying to deserialize a SOAP envelope with the intent to "parse" it. I am getting the following exception. What am I doing wrong?

System.InvalidOperationException: <Envelope xmlns='http://www.w3.org/2003/05/soap-envelope'>; was not expected.

Please see ParseResponse method below. Note: string parser is currently not used.

         private void ParseResponse(string parser, string output)
         {
             var serializer = new XmlSerializer(typeof(Parser.Envelope));
    
             using (var reader = new StringReader(output))
             {
                 var envelope = (Parser.Envelope)serializer.Deserialize(reader);
    
                 // Parse out desired information...
    
             }
         }

See class Parser below...

 public class Parser : ResponseParser
 {
     public Envelope envelope { get; set; }
    
     [XmlRoot(ElementName = "Envelope")]
     public class Envelope
     {
         [XmlElement(ElementName = "Header")]
         public Header Header { get; set; }
    
         [XmlElement(ElementName = "Body")]
         public Body Body { get; set; }
    
         [XmlAttribute(AttributeName = "xmlns")]
         public string Xmlns { get; set; }
    
         [XmlAttribute(AttributeName = "soap")]
         public string Soap { get; set; }
    
         [XmlAttribute(AttributeName = "xsi")]
         public string Xsi { get; set; }
    
         [XmlAttribute(AttributeName = "xsd")]
         public string Xsd { get; set; }
    
         [XmlAttribute(AttributeName = "wsa")]
         public string Wsa { get; set; }
    
         [XmlAttribute(AttributeName = "wsse")]
         public string Wsse { get; set; }
    
         [XmlAttribute(AttributeName = "wsu")]
         public string Wsu { get; set; }
    
         [XmlText]
         public string Text { get; set; }
     }
    
     [XmlRoot(ElementName = "Header")]
     public class Header
     {
         [XmlElement(ElementName = "Action")]
         public string Action { get; set; }
    
         [XmlElement(ElementName = "MessageID")]
         public string MessageID { get; set; }
    
         [XmlElement(ElementName = "RelatesTo")]
         public string RelatesTo { get; set; }
    
         [XmlElement(ElementName = "To")]
         public string To { get; set; }
    
         [XmlElement(ElementName = "Security")]
         public Security Security { get; set; }
    
         [XmlAttribute(AttributeName = "env")]
         public string Env { get; set; }
    
         [XmlText]
         public string Text { get; set; }
     }
    
     [XmlRoot(ElementName = "Security")]
     public class Security
     {
         [XmlElement(ElementName = "Timestamp")]
         public Timestamp Timestamp { get; set; }
     }
    
     [XmlRoot(ElementName = "Timestamp")]
     public class Timestamp
     {
    
         [XmlElement(ElementName = "Created")]
         public DateTime Created { get; set; }
    
         [XmlElement(ElementName = "Expires")]
         public DateTime Expires { get; set; }
    
         [XmlAttribute(AttributeName = "Id")]
         public string Id { get; set; }
    
         [XmlText]
         public string Text { get; set; }
     }
    
     [XmlRoot(ElementName = "Body")]
     public class Body
     {
         [XmlElement(ElementName = "MethodResponse")]
         public MethodResponse MethodResponse { get; set; }
     }
    
     [XmlRoot(ElementName = "MethodResponse")]
     public class MethodResponse
     {
         [XmlElement(ElementName = "MethodResult")]
         public MethodResult MethodResult { get; set; }
    
         [XmlAttribute(AttributeName = "xmlns")]
         public string Xmlns { get; set; }
    
         [XmlText]
         public string Text { get; set; }
     }
    
     [XmlRoot(ElementName = "MethodResult")]
     public class MethodResult
     {

         // SOAP Information

     }

Here is the response to be parsed...

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">;
<env:Header
xmlns:env="http://www.w3.org/2003/05/soap-envelope">;
<wsa:Action>http://company.com/MethodResponse</wsa:Action>;
<wsa:MessageID>urn:uuid:afc4a308-b476-4af2-8c9c-44a404e10623</wsa:MessageID>
<wsa:RelatesTo>urn:uuid:1f5b8e40-d48f-40bb-8c37-50d82afaa6a5</wsa:RelatesTo>
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>;
<wsse:Security>
<wsu:Timestamp wsu:Id="Timestamp-9b4fb7d0-a6d2-4757-9bf8-70ab62d45323">
<wsu:Created>2022-04-30T05:03:12Z</wsu:Created>
<wsu:Expires>2022-04-30T05:08:12Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</env:Header>
<soap:Body>
<MethodResponse
xmlns="http://company.com/">;
<MethodResult>
<!-- SOAP Information -->
</MethodResult>
</MethodResponse>
</soap:Body>
</soap:Envelope>

Let me know if you require additional information.

Thank-you!

dotnet-csharpdotnet-runtimedotnet-aspnet-generaldotnet-standarddotnet-aspnet-webpages
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

AgaveJoe avatar image
0 Votes"
AgaveJoe answered

The SOAP document is invalid as it contains an arbitrary semicolons. First, fix the SOAP document.

 <?xml version="1.0" encoding="utf-8"?>
 <soap:Envelope
 xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
 xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
     <env:Header
     xmlns:env="http://www.w3.org/2003/05/soap-envelope">
         <wsa:Action>http://company.com/MethodResponse</wsa:Action>
         <wsa:MessageID>urn:uuid:afc4a308-b476-4af2-8c9c-44a404e10623</wsa:MessageID>
         <wsa:RelatesTo>urn:uuid:1f5b8e40-d48f-40bb-8c37-50d82afaa6a5</wsa:RelatesTo>
         <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
         <wsse:Security>
             <wsu:Timestamp wsu:Id="Timestamp-9b4fb7d0-a6d2-4757-9bf8-70ab62d45323">
                 <wsu:Created>2022-04-30T05:03:12Z</wsu:Created>
                 <wsu:Expires>2022-04-30T05:08:12Z</wsu:Expires>
             </wsu:Timestamp>
         </wsse:Security>
     </env:Header>
     <soap:Body>
         <MethodResponse
         xmlns="http://company.com/">
             <MethodResult>
                 <!-- SOAP Information -->
             </MethodResult>
         </MethodResponse>
     </soap:Body>
 </soap:Envelope>


Visual Studio comes with robust XML APIs and utilities for deserializing XML. There's very little reason to write your own XML parser. Copy the XML then in Visual Studio clcik Edit -> Paste Special -> Paste XML as Classes.

     // NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
     /// <remarks/>
     [System.SerializableAttribute()]
     [System.ComponentModel.DesignerCategoryAttribute("code")]
     [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
     [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.w3.org/2003/05/soap-envelope", IsNullable = false)]
     public partial class Envelope
     {
    
         private EnvelopeHeader headerField;
    
         private EnvelopeBody bodyField;
    
         private string[] textField;
    
         /// <remarks/>
         public EnvelopeHeader Header
         {
             get
             {
                 return this.headerField;
             }
             set
             {
                 this.headerField = value;
             }
         }
    
         /// <remarks/>
         public EnvelopeBody Body
         {
             get
             {
                 return this.bodyField;
             }
             set
             {
                 this.bodyField = value;
             }
         }
    
         /// <remarks/>
         [System.Xml.Serialization.XmlTextAttribute()]
         public string[] Text
         {
             get
             {
                 return this.textField;
             }
             set
             {
                 this.textField = value;
             }
         }
     }
    
     /// <remarks/>
     [System.SerializableAttribute()]
     [System.ComponentModel.DesignerCategoryAttribute("code")]
     [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
     public partial class EnvelopeHeader
     {
    
         private string actionField;
    
         private string messageIDField;
    
         private string relatesToField;
    
         private string toField;
    
         private Security securityField;
    
         private string[] textField;
    
         /// <remarks/>
         [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://schemas.xmlsoap.org/ws/2004/08/addressing")]
         public string Action
         {
             get
             {
                 return this.actionField;
             }
             set
             {
                 this.actionField = value;
             }
         }
    
         /// <remarks/>
         [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://schemas.xmlsoap.org/ws/2004/08/addressing")]
         public string MessageID
         {
             get
             {
                 return this.messageIDField;
             }
             set
             {
                 this.messageIDField = value;
             }
         }
    
         /// <remarks/>
         [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://schemas.xmlsoap.org/ws/2004/08/addressing")]
         public string RelatesTo
         {
             get
             {
                 return this.relatesToField;
             }
             set
             {
                 this.relatesToField = value;
             }
         }
    
         /// <remarks/>
         [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://schemas.xmlsoap.org/ws/2004/08/addressing")]
         public string To
         {
             get
             {
                 return this.toField;
             }
             set
             {
                 this.toField = value;
             }
         }
    
         /// <remarks/>
         [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" +
             "")]
         public Security Security
         {
             get
             {
                 return this.securityField;
             }
             set
             {
                 this.securityField = value;
             }
         }
    
         /// <remarks/>
         [System.Xml.Serialization.XmlTextAttribute()]
         public string[] Text
         {
             get
             {
                 return this.textField;
             }
             set
             {
                 this.textField = value;
             }
         }
     }
    
     /// <remarks/>
     [System.SerializableAttribute()]
     [System.ComponentModel.DesignerCategoryAttribute("code")]
     [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" +
         "")]
     [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" +
         "", IsNullable = false)]
     public partial class Security
     {
    
         private Timestamp timestampField;
    
         /// <remarks/>
         [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xs" +
             "d")]
         public Timestamp Timestamp
         {
             get
             {
                 return this.timestampField;
             }
             set
             {
                 this.timestampField = value;
             }
         }
     }
    
     /// <remarks/>
     [System.SerializableAttribute()]
     [System.ComponentModel.DesignerCategoryAttribute("code")]
     [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xs" +
         "d")]
     [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xs" +
         "d", IsNullable = false)]
     public partial class Timestamp
     {
    
         private System.DateTime createdField;
    
         private System.DateTime expiresField;
    
         private string idField;
    
         /// <remarks/>
         public System.DateTime Created
         {
             get
             {
                 return this.createdField;
             }
             set
             {
                 this.createdField = value;
             }
         }
    
         /// <remarks/>
         public System.DateTime Expires
         {
             get
             {
                 return this.expiresField;
             }
             set
             {
                 this.expiresField = value;
             }
         }
    
         /// <remarks/>
         [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
         public string Id
         {
             get
             {
                 return this.idField;
             }
             set
             {
                 this.idField = value;
             }
         }
     }
    
     /// <remarks/>
     [System.SerializableAttribute()]
     [System.ComponentModel.DesignerCategoryAttribute("code")]
     [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
     public partial class EnvelopeBody
     {
    
         private MethodResponse methodResponseField;
    
         /// <remarks/>
         [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://company.com/")]
         public MethodResponse MethodResponse
         {
             get
             {
                 return this.methodResponseField;
             }
             set
             {
                 this.methodResponseField = value;
             }
         }
     }
    
     /// <remarks/>
     [System.SerializableAttribute()]
     [System.ComponentModel.DesignerCategoryAttribute("code")]
     [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://company.com/")]
     [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://company.com/", IsNullable = false)]
     public partial class MethodResponse
     {
    
         private object methodResultField;
    
         private string[] textField;
    
         /// <remarks/>
         public object MethodResult
         {
             get
             {
                 return this.methodResultField;
             }
             set
             {
                 this.methodResultField = value;
             }
         }
    
         /// <remarks/>
         [System.Xml.Serialization.XmlTextAttribute()]
         public string[] Text
         {
             get
             {
                 return this.textField;
             }
             set
             {
                 this.textField = value;
             }
         }
     }


The code is simply.

 Envelope envelope;
 var mySerializer = new XmlSerializer(typeof(Envelope));
 using (var myFileStream = new FileStream("SoapMessage.xml", FileMode.Open))
 {
     envelope = (Envelope)mySerializer.Deserialize(myFileStream);
 }

If you are calling an XML SOAP service then use the Service Reference tool to generate the code.

How to deserialize an object using XmlSerializer
How to: Add, update, or remove a WCF data service reference


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

JulioBello-4525 avatar image
0 Votes"
JulioBello-4525 answered

Hi, @AgaveJoe...

Thank-you for your prompt response.

I assure you that there are no semicolons in the actual SOAP document. I don't know how the semicolons got "injected" into the sanitized example above. Here is it again without semicolons.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">;
<env:Header
xmlns:env="http://www.w3.org/2003/05/soap-envelope">;
<wsa:Action>http://company.com/MethodResponse</wsa:Action>;
<wsa:MessageID>urn:uuid:afc4a308-b476-4af2-8c9c-44a404e10623</wsa:MessageID>
<wsa:RelatesTo>urn:uuid:1f5b8e40-d48f-40bb-8c37-50d82afaa6a5</wsa:RelatesTo>
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>;
<wsse:Security>
<wsu:Timestamp wsu:Id="Timestamp-9b4fb7d0-a6d2-4757-9bf8-70ab62d45323">
<wsu:Created>2022-04-30T05:03:12Z</wsu:Created>
<wsu:Expires>2022-04-30T05:08:12Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</env:Header>
<soap:Body>
<MethodResponse
xmlns="http://company.com/">;
<MethodResult>
// SOAP Information
</MethodResult>
</MethodResponse>
</soap:Body>
</soap:Envelope>

I created the template parser class using a third-party online tool. I will use the method you recommended using Visual Studio.

The code you provided is very similar to mine (see below). My goal is to create a parser for virtually any type of "data" file (XML, JSON, CSV, Tab/Pipe Delimited, etc.). Right now, string parser is a placeholder for some parameter to indicate which type of "data" file.


Yours

  Envelope envelope;
    
  var mySerializer = new XmlSerializer(typeof(Envelope));
    
  using (var myFileStream = new FileStream("SoapMessage.xml", FileMode.Open))
  {
      envelope = (Envelope)mySerializer.Deserialize(myFileStream);
  }

Mine

 private void ParseResponse(string parser, string output)
 {
     var serializer = new XmlSerializer(typeof(Parser.Envelope));
        
     using (var reader = new StringReader(output))
     {
         var envelope = (Parser.Envelope)serializer.Deserialize(reader);
        
         // Parse out desired information...
        
     }
 }

I will advise you of my progress.

Truly grateful,

Julio

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

JulioBello-4525 avatar image
0 Votes"
JulioBello-4525 answered

Hi, @AgaveJoe...

Eureka!... It worked!

THANK-YOU!

Though it's too verbose... I don't need all the field references. Just a simple { get; set; } will do.

Truly grateful,

Julio

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.