2015-12-03 9 views
15

Ho difficoltà a creare classi di deserializzazione per questo xml:creati automaticamente le classi C# per XML deserializzazione non funzionano

<?xml version="1.0" encoding="ISO-8859-1"?> 
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:stn="urn:response"> 
    <SOAP-ENV:Body> 
     <Response> 
      <Records xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="stn:Record[1]"> 
       <item xsi:type="stn:Record"> 
        <person xsi:type="xsd:string">John Johnos</person> 
        <address xsi:type="xsd:string">Some Street 1</address> 
        <age xsi:type="xsd:string">24</age> 
       </item> 
      </Records> 
      <status xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="stn:status[1]"> 
       <item xsi:type="stn:status"> 
        <status xsi:type="xsd:string">success</status> 
        <message xsi:type="xsd:string"/> 
       </item> 
      </status> 
     </Response> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

ho cercato di utilizzare codice creato automaticamente (in VisualStudio 12: Modifica -> Incolla speciale -> Incolla XML come classi):

/// <remarks/> 
[System.SerializableAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/soap/envelope/")] 
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.xmlsoap.org/soap/envelope/", IsNullable = false)] 
public partial class Envelope 
{ 

    private EnvelopeBody bodyField; 

    private string encodingStyleField; 

    /// <remarks/> 
    public EnvelopeBody Body 
    { 
     get 
     { 
      return this.bodyField; 
     } 
     set 
     { 
      this.bodyField = value; 
     } 
    } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)] 
    public string encodingStyle 
    { 
     get 
     { 
      return this.encodingStyleField; 
     } 
     set 
     { 
      this.encodingStyleField = value; 
     } 
    } 
} 

/// <remarks/> 
[System.SerializableAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/soap/envelope/")] 
public partial class EnvelopeBody 
{ 

    private Response responseField; 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "")] 
    public Response Response 
    { 
     get 
     { 
      return this.responseField; 
     } 
     set 
     { 
      this.responseField = value; 
     } 
    } 
} 

/// <remarks/> 
[System.SerializableAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] 
public partial class Response 
{ 

    private ResponseRecords recordsField; 

    private ResponseStatus statusField; 

    /// <remarks/> 
    public ResponseRecords Records 
    { 
     get 
     { 
      return this.recordsField; 
     } 
     set 
     { 
      this.recordsField = value; 
     } 
    } 

    /// <remarks/> 
    public ResponseStatus status 
    { 
     get 
     { 
      return this.statusField; 
     } 
     set 
     { 
      this.statusField = value; 
     } 
    } 
} 

/// <remarks/> 
[System.SerializableAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
public partial class ResponseRecords 
{ 

    private ResponseRecordsItem itemField; 

    private string arrayTypeField; 

    /// <remarks/> 
    public ResponseRecordsItem item 
    { 
     get 
     { 
      return this.itemField; 
     } 
     set 
     { 
      this.itemField = value; 
     } 
    } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://schemas.xmlsoap.org/soap/encoding/")] 
    public string arrayType 
    { 
     get 
     { 
      return this.arrayTypeField; 
     } 
     set 
     { 
      this.arrayTypeField = value; 
     } 
    } 
} 

/// <remarks/> 
[System.SerializableAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
public partial class ResponseRecordsItem 
{ 

    private string personField; 

    private string addressField; 

    private byte ageField; 

    /// <remarks/> 
    public string person 
    { 
     get 
     { 
      return this.personField; 
     } 
     set 
     { 
      this.personField = value; 
     } 
    } 

    /// <remarks/> 
    public string address 
    { 
     get 
     { 
      return this.addressField; 
     } 
     set 
     { 
      this.addressField = value; 
     } 
    } 

    /// <remarks/> 
    public byte age 
    { 
     get 
     { 
      return this.ageField; 
     } 
     set 
     { 
      this.ageField = value; 
     } 
    } 
} 

/// <remarks/> 
[System.SerializableAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
public partial class ResponseStatus 
{ 

    private ResponseStatusItem itemField; 

    private string arrayTypeField; 

    /// <remarks/> 
    public ResponseStatusItem item 
    { 
     get 
     { 
      return this.itemField; 
     } 
     set 
     { 
      this.itemField = value; 
     } 
    } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://schemas.xmlsoap.org/soap/encoding/")] 
    public string arrayType 
    { 
     get 
     { 
      return this.arrayTypeField; 
     } 
     set 
     { 
      this.arrayTypeField = value; 
     } 
    } 
} 

/// <remarks/> 
[System.SerializableAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
public partial class ResponseStatusItem 
{ 

    private string statusField; 

    private object messageField; 

    /// <remarks/> 
    public string status 
    { 
     get 
     { 
      return this.statusField; 
     } 
     set 
     { 
      this.statusField = value; 
     } 
    } 

    /// <remarks/> 
    public object message 
    { 
     get 
     { 
      return this.messageField; 
     } 
     set 
     { 
      this.messageField = value; 
     } 
    } 
} 

ho cercato di deserializzare con l'aiuto di XMLSerializer:

var serializer = new XmlSerializer(typeof(Envelope)); 
var reader = new StringReader(response); 
var flResponse = (Envelope)serializer.Deserialize(reader); 

Il messaggio di errore che ho ottenuto:

Message=The specified type was not recognized: name='Array', namespace='http://schemas.xmlsoap.org/soap/encoding/', at <Records xmlns=''>. 

la prego di aiutarmi a classi di deserializzazione greate per questo XML?

+1

puoi mostrare la tua classe Busta? O questa classe Envelope generata automaticamente è quella che hai usato in Serializer XML? – Angloos

+1

Ho usato questo auto-generato. – belurd

+2

Se vuoi solo correggere l'XML che è stato creato, puoi guardare [questo esempio] (http://siderite.blogspot.com/2014/01/deserializingserializing-xml-that.html).Sembra che gli attributi xsi: type causino un comportamento strano. – DHP

risposta

5

Ho provato un sacco di cose e finalmente l'ho capito. L'Xml che hai postato non è valido perché xsi: type non funziona nella deserializzazione.

XML valido dovrebbe essere simile:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:stn="urn:response"> 
    <SOAP-ENV:Body> 
     <Response> 
      <Records> 
       <item> 
        <person >John Johnos</person> 
        <address >Some Street 1</address> 
        <age >24</age> 
       </item> 
      </Records> 
      <status> 
       <item> 
        <status >success</status> 
        <message/> 
       </item> 
      </status> 
     </Response> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

Codice poi dovrebbe assomigliare:

XDocument xml = XDocument.Parse(xmlInput); 

XmlSerializer serializer = new XmlSerializer(typeof(Response)); 

using (StringReader stream = new StringReader(items[0].ToString())) 
{ 
    var output = (Response)serializer.Deserialize(stream); 
} 

classe Genera automaticamente sarà da:

<Response> 
    <Records xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <item> 
     <person>John Johnos</person> 
     <address >Some Street 1</address> 
     <age>24</age> 
    </item> 
    </Records> 
    <status xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <item > 
     <status >success</status> 
     <message /> 
    </item> 
    </status> 
</Response> 

Spero che questo è abbastanza chiaro. Non sei sicuro di come eliminare i tipi da Envelope, quindi probabilmente non è la soluzione che desideri.

Il metodo che utilizzo per ottenere le cose da Busta è XDocument.Descendants(elemmentName) quale matrice di restituzione o Elenco di elementi di tale nome e quindi è possibile riempire gli oggetti. È più lavoro, ma penso sia meglio che trasformare xml per la deserializzazione.

+1

Ciao. Grazie per le indagini. Questo è in realtà ciò che ho fatto alla fine: cercato attraverso l'xml e cancellato tutte le parti fastidiose e deserializzare l'XML pulito in seguito. Ma non penso che sia giusto per il sistema di produzione. Questo è troppo sporco per solo stringhe. Sostituire() cose. L'XML che ho non è quello che posso controllare. È un servizio di terze parti che devo usare. – belurd

+1

Allo stesso tempo, penso che sia possibile deserializzare con questo xsi: type, ma non so come :-( – belurd

+1

prova 'XDocument.Descendants (elemmentName)' per esempio 'XDocument.Descendants (" item ") 'ottieni un array di stringhe e quindi puoi usare' item.Descendants ("person"). FirstOrDefault(). Value' che ti dà 'John Johnos' – Slasko

5

Perché non generare una libreria di serializzazione per l'intero schema?

  1. Scaricare il file di schema XSD dall'URL nel messaggio e salvarlo da qualche parte

    http://schemas.xmlsoap.org/soap/encoding/

  2. Aprire un Visual Studio Command Prompt e digitare il seguente comando

    XSD/classes SoapEncoding.xsd

  3. L'output sarà un file denominato SoapEncoding.cs.

  4. Importare questo file nel progetto e provare a deserializzare nuovamente il messaggio.

Se tutto va bene, tutto dovrebbe funzionare questa volta.

+1

Ho provato in questo modo. Non ha funzionato. Inoltre, chiedi aiuto ai miei colleghi e non siamo riusciti a trovare ciò che è sbagliato tutti insieme. – belurd

+1

L'approccio che ho suggerito dovrebbe funzionare. Potresti fornire alcuni dettagli su quali errori stai ricevendo utilizzando il mio approccio? – Randy

Problemi correlati