在没有 XmlAttributes 的情况下反序列化来自 XML 的通用列表 <T>
Deserializing Generic List<T> From XML Without XmlAttributes
我正在尝试将 xml 列表反序列化为 C# 中的通用列表。我不想使用 XmlAttributes,因为解决方案需要通用。我必须接近了,因为我得到了 3 个 Item 对象,但它们都填充了默认值,即:null 或 0。
这不是 how to deserialize an xml node with a value and an attribute using asp.net serialization 的副本,它使用 XmlAttributes 并且不是一个选项。这在问题中有明确说明。
有许多我已经尝试过的 SO 答案,它们与我需要的相似,包括 [Duplicate] 中的其他 SO 响应列表。下面的代码是根据其中一个答案修改的,但效果不佳。
<?xml version="1.0" encoding="utf-8"?>
<root>
---snip---
<Items>
<Item ItemId="1" ItemName="TestName1" Number="100" Created=""></Item>
<Item ItemId="2" ItemName="TestName2" Number="200" Created=""></Item>
<Item ItemId="3" ItemName="TestName3" Number="300" Created=""></Item>
</Items>
</root>
========================================================
var sourceData = XDocument.Parse(xml);
public List<T> GetObjectList<T>(string identifier) where T : class, new()
{
if (sourceData != null && !identifier.isNullOrEmpty())
{
var list = sourceData.Descendants(identifier)
.Select(p => DeserializeObject<T>(p.ToString()))
.ToList();
return list;
}
return new List<T>();
}
public static T DeserializeObject<T>(string xml) where T : class, new()
{
if (string.IsNullOrEmpty(xml))
{
return default(T);
}
try
{
using (var stringReader = new StringReader(xml))
{
var serializer = new XmlSerializer(typeof(T));
return (T) serializer.Deserialize(stringReader);
}
}
catch
{
return default(T);
}
}
public class Item
{
public int ItemId { get; set; }
public string ItemName { get; set; }
public int? Number { get; set;}
public DateTime? Created { get; set; }
}
// RESULT
// Item ItemId="0" ItemName="null" Number="null" Created="null"
// Item ItemId="0" ItemName="null" Number="null" Created="null"
// Item ItemId="0" ItemName="null" Number="null" Created="null"
检查 XmlSerialzer 构造函数,如果您不想修改 class,您可以在那里指定属性覆盖——您将需要一些数据来定义您在某些时候序列化的内容;如果没有这些属性或已知可序列化的类型(数字、字符串等),XmlSerializer 从未被编写为可以工作。
如果你想成为通用的,你将不得不编写你自己的序列化器,它使用反射来决定序列化什么、如何序列化、以什么顺序序列化,以及忽略什么。在序列化具有必要属性的类型时,您可以在其中使用 XmlSerializer。搜索解释如何实现 IXmlSerializable 的教程,它们将向您展示如何使用 XmlWriter / XmlReader 来避免自己处理 XML 语法。
猜猜为什么会这样:循环引用使(反)序列化非常困难,通用解决方案可能会尝试序列化它而不会结束,导致调用永远挂起的奇怪错误,当一些开发人员更改了其中一个 classes 而看不到(由于那里没有属性)他们必须以一种避免序列化问题的方式编写 class。
我问了另一个类似的问题 (),当时这个问题被标记为重复(有一段时间)并最终创建了一个满足我需要的简单自定义反序列化器。如果有兴趣,请查看代码的答案。
我正在尝试将 xml 列表反序列化为 C# 中的通用列表。我不想使用 XmlAttributes,因为解决方案需要通用。我必须接近了,因为我得到了 3 个 Item 对象,但它们都填充了默认值,即:null 或 0。
这不是 how to deserialize an xml node with a value and an attribute using asp.net serialization 的副本,它使用 XmlAttributes 并且不是一个选项。这在问题中有明确说明。
有许多我已经尝试过的 SO 答案,它们与我需要的相似,包括 [Duplicate] 中的其他 SO 响应列表。下面的代码是根据其中一个答案修改的,但效果不佳。
<?xml version="1.0" encoding="utf-8"?>
<root>
---snip---
<Items>
<Item ItemId="1" ItemName="TestName1" Number="100" Created=""></Item>
<Item ItemId="2" ItemName="TestName2" Number="200" Created=""></Item>
<Item ItemId="3" ItemName="TestName3" Number="300" Created=""></Item>
</Items>
</root>
========================================================
var sourceData = XDocument.Parse(xml);
public List<T> GetObjectList<T>(string identifier) where T : class, new()
{
if (sourceData != null && !identifier.isNullOrEmpty())
{
var list = sourceData.Descendants(identifier)
.Select(p => DeserializeObject<T>(p.ToString()))
.ToList();
return list;
}
return new List<T>();
}
public static T DeserializeObject<T>(string xml) where T : class, new()
{
if (string.IsNullOrEmpty(xml))
{
return default(T);
}
try
{
using (var stringReader = new StringReader(xml))
{
var serializer = new XmlSerializer(typeof(T));
return (T) serializer.Deserialize(stringReader);
}
}
catch
{
return default(T);
}
}
public class Item
{
public int ItemId { get; set; }
public string ItemName { get; set; }
public int? Number { get; set;}
public DateTime? Created { get; set; }
}
// RESULT
// Item ItemId="0" ItemName="null" Number="null" Created="null"
// Item ItemId="0" ItemName="null" Number="null" Created="null"
// Item ItemId="0" ItemName="null" Number="null" Created="null"
检查 XmlSerialzer 构造函数,如果您不想修改 class,您可以在那里指定属性覆盖——您将需要一些数据来定义您在某些时候序列化的内容;如果没有这些属性或已知可序列化的类型(数字、字符串等),XmlSerializer 从未被编写为可以工作。
如果你想成为通用的,你将不得不编写你自己的序列化器,它使用反射来决定序列化什么、如何序列化、以什么顺序序列化,以及忽略什么。在序列化具有必要属性的类型时,您可以在其中使用 XmlSerializer。搜索解释如何实现 IXmlSerializable 的教程,它们将向您展示如何使用 XmlWriter / XmlReader 来避免自己处理 XML 语法。
猜猜为什么会这样:循环引用使(反)序列化非常困难,通用解决方案可能会尝试序列化它而不会结束,导致调用永远挂起的奇怪错误,当一些开发人员更改了其中一个 classes 而看不到(由于那里没有属性)他们必须以一种避免序列化问题的方式编写 class。
我问了另一个类似的问题 (