关于asp.net:Deserializing XML to C#Object返回null值

Deserializing XML to C# Object returning null values

在试图获取价值时??来自WebService的XML文本,值是多少??如下图所示为空。

代码

1
2
3
4
5
6
7
8
9
10
11
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));

返回变量ei

enter image description here

编辑

据我所见,返回的不是ListaMensagemRetorno字段。这是问题吗?

服务参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
[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;
        }
    }
}


问题

基于您的示例,这里的问题是您在试图反序列化的XML字符串和反序列化对象本身之间有不同的XML Namespace声明。

在XML字符串中,XML没有用于EnviarLoteRpsResposta的XML命名空间声明(没有默认命名空间):

1
2
3
4
5
6
7
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>";

在您的EnviarLoteRpsResposta类中,XML命名空间声明为http://www.e-governeapps2.com.br/

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

< BR>

解决办法

要使反序列化工作,需要执行以下操作之一:

  • 更改EnviarLoteRpsResposta类并删除XML命名空间声明:

    1
    2
    3
    ...
    /* REMOVED [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.e-governeapps2.com.br/")] */
    public partial class EnviarLoteRpsResposta { ... }
  • 或者…更改Web服务并将适当的XML命名空间添加到返回的XML字符串中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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>";

    然后稍微更改代码以将XML字符串反序列化为:

    1
    2
    3
     ...
     XmlRootAttribute rootAttribute = new XmlRootAttribute("EnviarLoteRpsResposta") { Namespace ="http://www.e-governeapps2.com.br/" };        
     ...
  • 或者…更改用于反序列化XML字符串的代码,并以编程方式添加适当的XML命名空间(不更改EnviarLoteRpsResposta类或Web服务):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ...
    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));
    ...