将 REST XML 响应反序列化为对象 - 在有效 XML 上失败

Deserialising REST XML response into object - failing on valid XML

我尝试反序列化从 REST Web 服务器获得的 xml 文档对象。这是我从服务器得到的确切响应(有效 XML):

<?xml version="1.0" encoding="utf-8"?>
<ads:body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:ads="http://www.ads.org/AnimalDataSchema">
    <ads:header>
        <ads:createdBy>Polaris</ads:createdBy>
        <ads:dateTimeCreated>2016-01-20T10:22:23Z</ads:dateTimeCreated>
    </ads:header>
    <ads:animals count="2">
        <ads:animal>
            <ads:internalIdentifier>1</ads:internalIdentifier>
            <ads:eid>982 000360237659</ads:eid>
            <ads:dob>2012-05-01</ads:dob>
            <ads:breed>Angus</ads:breed>
            <ads:customLifeTimeData>
                <ads:name>VID</ads:name>
                <ads:value>TTDEMO1</ads:value>
            </ads:customLifeTimeData>
        </ads:animal>
        <ads:animal>
            <ads:internalIdentifier>2</ads:internalIdentifier>
            <ads:eid>982 000359951630</ads:eid>
            <ads:dob>2012-05-02</ads:dob>
            <ads:breed>Angus</ads:breed>
            <ads:customLifeTimeData>
                <ads:name>VID</ads:name>
                <ads:value>TTDEMO2</ads:value>
            </ads:customLifeTimeData>
        </ads:animal>
    </ads:animals>
</ads:body>

我用来反序列化的对象 class 是这样的:

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace ***.IOT.Schemas
{
    public class ADI_animal
    {
        [XmlRoot(ElementName = "header", Namespace = "http://www.ads.org/AnimalDataSchema")]
        public class Header
        {
            [XmlElement(ElementName = "createdBy", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public string CreatedBy { get; set; }
            [XmlElement(ElementName = "dateTimeCreated", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public string DateTimeCreated { get; set; }
        }

        [XmlRoot(ElementName = "customLifeTimeData", Namespace = "http://www.ads.org/AnimalDataSchema")]
        public class CustomLifeTimeData
        {
            [XmlElement(ElementName = "name", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public string Name { get; set; }
            [XmlElement(ElementName = "value", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public string Value { get; set; }
        }

        [XmlRoot(ElementName = "animal", Namespace = "http://www.ads.org/AnimalDataSchema")]
        public class Animal
        {
            [XmlElement(ElementName = "internalIdentifier", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public string InternalIdentifier { get; set; }
            [XmlElement(ElementName = "eid", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public string Eid { get; set; }
            [XmlElement(ElementName = "dob", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public string Dob { get; set; }
            [XmlElement(ElementName = "breed", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public string Breed { get; set; }
            [XmlElement(ElementName = "customLifeTimeData", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public CustomLifeTimeData CustomLifeTimeData { get; set; }
        }

        [XmlRoot(ElementName = "animals", Namespace = "http://www.ads.org/AnimalDataSchema")]
        public class Animals
        {
            [XmlElement(ElementName = "animal", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public List<Animal> Animal { get; set; }
            [XmlAttribute(AttributeName = "count")]
            public string Count { get; set; }
        }

        [XmlRoot(ElementName = "body", Namespace = "http://www.ads.org/AnimalDataSchema")]

        public class Body
        {
            [XmlElement(ElementName = "header", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public Header Header { get; set; }
            [XmlElement(ElementName = "animals", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public Animals Animals { get; set; }
            [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
            public string Xsi { get; set; }
            [XmlAttribute(AttributeName = "ads", Namespace = "http://www.ads.org/AnimalDataSchema")]
            public string Ads { get; set; }
        }

    }
}

调试输出为:

Exception thrown: 'System.InvalidOperationException' in Microsoft.GeneratedCode
The thread 0xdfc has exited with code 0 (0x0).
The thread 0xb34 has exited with code 0 (0x0).
Exception thrown: 'System.Reflection.TargetInvocationException' in mscorlib.ni.dll
Exception thrown: 'System.InvalidOperationException' in System.Xml.XmlSerializer.dll
exception caught: There is an error in XML document (1, 40).

代码我运行:

   static public void ProcessResponse(XmlDocument queryResponse)
   {
            String queryRootString;
            ADI_animal adsObject = new ADI_animal();
            using (var stringWriter = new StringWriter())
            using (var xmlTextWriter = XmlWriter.Create(stringWriter))
            {
                XmlDocument queryRoot = queryResponse;
                queryRoot.WriteTo(xmlTextWriter);
                xmlTextWriter.Flush();
                queryRootString = stringWriter.GetStringBuilder().ToString();
            }
            try
            {
                XmlSerializer result = new XmlSerializer(typeof(ADI_animal));

                adsObject = (ADI_animal)result.Deserialize(new StringReader(queryRootString));
            }
            catch (Exception ex)
            {
                Debug.WriteLine("exception caught: " + ex.Message);
            }
}

几乎告诉我 XML 文档的命名空间有问题。但我就是找不到错误。也许有人可以给我一个正确的方向?

您正在尝试通过配置为期望 ADI_animal 作为顶级对象的序列化程序反序列化看起来像 ADI_animal.Body 的 XML。

不确定您在寻找什么,但是将 XML 反序列化为 ADI_animal.Body 实例应该可以正常工作:

XmlSerializer result = new XmlSerializer(typeof(ADI_animal.Body));
var body = (ADI_animal.Body)result.Deserialize(new StringReader(queryRootString));

调试说明:为了简化反序列化的调查,首先尝试序列化对象以查看 XML 的预期形状:

XmlSerializer result2 = new XmlSerializer(typeof(ADI_animal));
var w = new StringWriter();
result2.Serialize(w, new ADI_animal());
Console.WriteLine(w.ToString());