C#xml反序列化忽略List<>属性意外

时间:2015-04-26 14:21:41

标签: c# xml serialization .net-4.5

因为XmlSerializer不能在字典上工作,所以我在它们上使用XmlIgnore属性,并使用中介List<>将字典呈现为列表的属性, 使用序列化。但是,我的列表<>反序列化时忽略属性。 (没有抛出错误,也没有引发序列化事件。)为什么?

[XmlIgnore]
public Dictionary<string, string> ConnectionStrings { get; set; }

这是应该用于de / serialization的“surrogate”列表属性。就像我说的,这适用于序列化,但在反序列化过程中会忽略该属性。我想知道为什么/该做些什么......

public List<ConnectionItem> SerializedConnections
{
    get 
    { 
        return ConnectionStrings.Select(keyPair => new ConnectionItem() { Name = keyPair.Key, ConnectionString = keyPair.Value }).ToList(); 
    }
    set 
    {
        ConnectionStrings = new Dictionary<string, string>();
        foreach (var ci in value) ConnectionStrings.Add(ci.Name, ci.ConnectionString);
    }
}

我尝试在我的SerializedConnections属性的set访问器中设置断点,但它从未被命中。

1 个答案:

答案 0 :(得分:1)

这永远不会像你假设的那样起作用。在反序列化期间,XmlSerializer 调用getter 以检索可能为空的List<T>实例,然后调用其Add(T item)方法以使用反序列化的对象填充它。

documentation in MSDN特别说:

  

XmlSerializer为实现IEnumerableICollection的类提供特殊处理。实现IEnumerable的类必须实现采用单个参数的公共Add方法。 Add方法的参数必须与从Current返回的值GetEnumerator属性返回的类型相同,或者是该类型的基础之一。除了ICollection之外,实现CollectionBase的类(例如IEnumerable)必须具有公共Item索引属性(C#中的索引器),它采用整数,并且必须有一个整数类型的公共Count属性。 Add方法的参数必须与从Item属性返回的类型相同,或者是该类型的基础之一。对于实现ICollection的类,要从序列化的Item属性中检索要序列化的值,而不是通过调用GetEnumerator

您的设计的核心问题是SerializedConnections属性将表现为数据生成器。换句话说,每次调用getter时都会返回一个新的实例。属性不应该像只有那样的方法才能工作。

可能的解决方案是实现实现IList<ConnectionItem>并使用Dictionary<string, string>作为后备存储的自定义集合。然后,ConnectionStrings属性或更好的私有字段将属于此自定义类型,并且SerializedConnections属性在序列化/反序列化期间将正常运行。