将 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());
我尝试反序列化从 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());