mtsys
mtsys

Reputation: 249

Deserializing XML to C# Object returning null values

When trying to get the values ​​from the XML text that comes from a WebService, the values ​​are null as the image below.

Code

string texto = 
    "<?xml version=\"1.0\"?>" + 
    "<EnviarLoteRpsResposta xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"+
    "   <NumeroLote>3774</NumeroLote>" +
    "   <DataRecebimento>2014-09-03T23:03:57.3428675-03:00</DataRecebimento>" +
    "   <Protocolo>635453822373428675</Protocolo>" +
    "</EnviarLoteRpsResposta>";
            
XmlRootAttribute rootAttribute = new XmlRootAttribute("EnviarLoteRpsResposta");
XmlSerializer serializer = new XmlSerializer(typeof(WS.NF.EnviarLoteRpsResposta), rootAttribute);
WS.NF.EnviarLoteRpsResposta ei = (WS.NF.EnviarLoteRpsResposta)serializer.Deserialize(new StringReader(texto)); 

Return variabble ei

enter image description here

Edit

From what I saw, the return is not the ListaMensagemRetorno field. Is this the problem?

Service Reference

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.e-governeapps2.com.br/")]
public partial class EnviarLoteRpsResposta {
        
    private System.Nullable<ulong> numeroLoteField;
        
    private System.Nullable<System.DateTime> dataRecebimentoField;
        
    private string protocoloField;
        
    private MensagemRetorno[] listaMensagemRetornoField;
        
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
    public System.Nullable<ulong> NumeroLote {
        get {
            return this.numeroLoteField;
        }
        set {
            this.numeroLoteField = value;
        }
    }
        
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
    public System.Nullable<System.DateTime> DataRecebimento {
        get {
            return this.dataRecebimentoField;
        }
        set {
            this.dataRecebimentoField = value;
        }
    }
        
    /// <remarks/>
    public string Protocolo {
        get {
            return this.protocoloField;
        }
        set {
            this.protocoloField = value;
        }
    }
        
    /// <remarks/>
    public MensagemRetorno[] ListaMensagemRetorno {
        get {
            return this.listaMensagemRetornoField;
        }
        set {
            this.listaMensagemRetornoField = value;
        }
    }
}

Upvotes: 2

Views: 6395

Answers (1)

IronGeek
IronGeek

Reputation: 4873

The Problem

Based on your example, the problem here is you have different XML Namespace declaration between the XML string you're trying to deserialize and the deserialized object itself.

In the XML string, the XML does not have an XML Namespace declaration for EnviarLoteRpsResposta (no default namespace):

string texto = 
    "<?xml version=\"1.0\"?>" + 
    "<EnviarLoteRpsResposta xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"+
    "   <NumeroLote>3774</NumeroLote>" +
    "   <DataRecebimento>2014-09-03T23:03:57.3428675-03:00</DataRecebimento>" +
    "   <Protocolo>635453822373428675</Protocolo>" +
    "</EnviarLoteRpsResposta>";

While in your EnviarLoteRpsResposta class, the XML Namespace is declared as http://www.e-governeapps2.com.br/:

...
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.e-governeapps2.com.br/")]
public partial class EnviarLoteRpsResposta { ... }  


The Workarounds

In order for the deserialization to work, you need to do ONE of the following:

  1. Change the EnviarLoteRpsResposta class and remove the XML Namespace declaration:

    ...
    /* REMOVED [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.e-governeapps2.com.br/")] */
    public partial class EnviarLoteRpsResposta { ... }
    
  2. Or... Change the web service and add the appropriate XML Namespace to the returned XML string:

    string texto = 
        "<?xml version=\"1.0\"?>" + 
        "<EnviarLoteRpsResposta 
           xmlns=\"http://www.e-governeapps2.com.br/\" 
           xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" 
           xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"+
        "   <NumeroLote>3774</NumeroLote>" +
        "   <DataRecebimento>2014-09-03T23:03:57.3428675-03:00</DataRecebimento>" +
        "   <Protocolo>635453822373428675</Protocolo>" +
        "</EnviarLoteRpsResposta>";  
    

    Then slightly change the code to deserialize the XML string to:

     ...
     XmlRootAttribute rootAttribute = new XmlRootAttribute("EnviarLoteRpsResposta") { Namespace = "http://www.e-governeapps2.com.br/" };         
     ...
    
  3. Or... Change the code for deserializing the XML string and add the approriate XML Namespace programmaticaly (no change to EnviarLoteRpsResposta class or the web service):

    ...
    NameTable nt = new NameTable();
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
    nsmgr.AddNamespace(String.Empty, "http://www.e-governeapps2.com.br/");
    XmlParserContext context = new XmlParserContext(nt, nsmgr, null, XmlSpace.None);
    
    XmlRootAttribute rootAttribute = new XmlRootAttribute("EnviarLoteRpsResposta") { Namespace = "http://www.e-governeapps2.com.br/" };
    XmlSerializer serializer = new XmlSerializer(typeof(WS.NF.EnviarLoteRpsResposta), rootAttribute);
    WS.NF.EnviarLoteRpsResposta ei = (WS.NF.EnviarLoteRpsResposta)serializer.Deserialize(new XmlTextReader(texto, XmlNodeType.Element, context));
    ...
    

Upvotes: 6

Related Questions