无法反序列化 XDocument
Unable do deserialize XDocument
我正在尝试将 XDocument 反序列化为包含 array/list 的 class。问题是这段代码没有这样做,我总是得到一个 Response
class 没有任何库存项目(不是 null,但计数 = 0)
这是我的测试方法:
public void GetObj()
{
var xe = new XElement("Inventory");
var xe2 = new XElement("Id", "23");
xe.Add(xe2);
var list = new List<XElement>();
list.Add(xe);
list.Add(xe);
var doc = new XDocument(new XElement("Response", list));
var obj = doc.Deserialize<Response>();
}
下面是我的扩展方法和模型:
public static class XDocumentExtensions
{
public static T Deserialize<T>(this XDocument doc)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (var reader = doc.Root.CreateReader())
{
return (T)xmlSerializer.Deserialize(reader);
}
}
public static XDocument Serialize<T>(this T value)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
XDocument doc = new XDocument();
using (var writer = doc.CreateWriter())
{
xmlSerializer.Serialize(writer, value);
}
return doc;
}
}
public class Response
{
public List<Inventory> Inventory { get; set; }
}
public class Inventory
{
public int Id { get; set; }
}
诊断 XML 反序列化问题的最简单方法是在内存中构建模型实例并将其序列化,然后将输出 XML 与所需输入进行比较。因此,如果我这样做:
Console.WriteLine(new Response { Inventory = new List<Inventory> { new Inventory { Id = 23 } } }.Serialize() );
输出XML是:
<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Inventory>
<Inventory>
<Id>23</Id>
</Inventory>
</Inventory>
</Response>
如您所见,<Inventory>
元素还有一层额外的嵌套。它在那里是因为,默认情况下,XmlSerializer
使用以序列化成员命名的外部容器元素元素(此处为 Inventory
)以及每个项目的元素(默认情况下)以项目类型(这里也是 Inventory
)。演示 fiddle #1 here.
如果您不想这样,您需要将 [XmlElement]
添加到 public List<Inventory>
,如下所示:
public class Response
{
[XmlElement]
public List<Inventory> Inventory { get; set; }
}
现在 Inventory
将在没有外部容器元素的情况下进行序列化,因此您的反序列化代码将会成功。演示 fiddle #2 here.
(或者,您可以使用必要的额外嵌套级别构建 XDocument
。)
我正在尝试将 XDocument 反序列化为包含 array/list 的 class。问题是这段代码没有这样做,我总是得到一个 Response
class 没有任何库存项目(不是 null,但计数 = 0)
这是我的测试方法:
public void GetObj()
{
var xe = new XElement("Inventory");
var xe2 = new XElement("Id", "23");
xe.Add(xe2);
var list = new List<XElement>();
list.Add(xe);
list.Add(xe);
var doc = new XDocument(new XElement("Response", list));
var obj = doc.Deserialize<Response>();
}
下面是我的扩展方法和模型:
public static class XDocumentExtensions
{
public static T Deserialize<T>(this XDocument doc)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (var reader = doc.Root.CreateReader())
{
return (T)xmlSerializer.Deserialize(reader);
}
}
public static XDocument Serialize<T>(this T value)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
XDocument doc = new XDocument();
using (var writer = doc.CreateWriter())
{
xmlSerializer.Serialize(writer, value);
}
return doc;
}
}
public class Response
{
public List<Inventory> Inventory { get; set; }
}
public class Inventory
{
public int Id { get; set; }
}
诊断 XML 反序列化问题的最简单方法是在内存中构建模型实例并将其序列化,然后将输出 XML 与所需输入进行比较。因此,如果我这样做:
Console.WriteLine(new Response { Inventory = new List<Inventory> { new Inventory { Id = 23 } } }.Serialize() );
输出XML是:
<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Inventory>
<Inventory>
<Id>23</Id>
</Inventory>
</Inventory>
</Response>
如您所见,<Inventory>
元素还有一层额外的嵌套。它在那里是因为,默认情况下,XmlSerializer
使用以序列化成员命名的外部容器元素元素(此处为 Inventory
)以及每个项目的元素(默认情况下)以项目类型(这里也是 Inventory
)。演示 fiddle #1 here.
如果您不想这样,您需要将 [XmlElement]
添加到 public List<Inventory>
,如下所示:
public class Response
{
[XmlElement]
public List<Inventory> Inventory { get; set; }
}
现在 Inventory
将在没有外部容器元素的情况下进行序列化,因此您的反序列化代码将会成功。演示 fiddle #2 here.
(或者,您可以使用必要的额外嵌套级别构建 XDocument
。)