在没有XmlAttributes的情况下从XML反序列化通用列表<t>

时间:2018-01-06 05:08:16

标签: c# linq deserialization linq-to-xml

我正在尝试将xml列表反序列化为C#中的通用List。我不想使用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"

2 个答案:

答案 0 :(得分:1)

检查XmlSerialzer构造函数,你可以在那里指定属性覆盖,如果你不想修改类 - 你需要一些数据来定义你在某些时候序列化的内容;如果没有这些属性,或者已知可序列化的类型(数字,字符串......),XmlSerializer从未编写为工作。

如果您想成为通用的,那么您必须编写自己的序列化程序,它使用反射来决定序列化的内容,方式,顺序以及忽略的内容。在序列化具有必要属性的类型时,可以在其中使用XmlSerializer。搜索解释如何实现IXmlSerializable的教程,他们将向您展示如何使用XmlWriter / XmlReader来避免自己处理XML语法。

猜测为什么会这样:循环引用使(de-)序列化变得非常困难,并且通用解决方案可能会尝试序列化它而不会结束,导致一些开发人员永远挂起的奇怪错误更改其中一个类而不能看到(由于没有属性)他们必须以避免序列化问题的方式编写类。

答案 1 :(得分:0)

我问了另一个类似的问题(A Better XElement to Object Without XMLAttributes in C#),当这个问题被标记为重复(一段时间)并最终创建了一个满足我需要的简单自定义反序列化器。如果感兴趣的话,请参阅那里的答案。