在反序列化CDATA时,集合是只读异常

时间:2012-08-30 14:46:10

标签: c# cdata xml-deserialization

我想反序列化包含CDATA集合的序列化XML。

XML看起来像这样:

<User Index="1">
   <Address><![CDATA[My street 1, 1234, My city]]></Address>
   <Address><![CDATA[My next street 1, 5678, My another city]]></Address>
</User>

因为我想直接将新地址添加为字符串,如下所示:

var user = new User();
user.Addresses.Add("My street 1, 1234, My city");
user.Addresses.Add("My next street 1, 5678, My another city");

我的用户类看起来像这样:

[XmlRoot("User", IsNullable = true)]
public class User
{
    [XmlIgnore]
    private XmlDocument xmlDoc;

    [XmlIgnore]
    private Collection<string> addresses;

    [XmlIgnore]
    private Collection<XmlNode> addressesNode;

    public User()
    {
        xmlDoc = new XmlDocument();
        addresses = new Collection<string>();
    }

    [XmlAttribute("Index")]
    public int Index { get; set; }

    [XmlElement("Address", IsNullable = true)]
    public Collection<XmlNode> AddressesNode
    {
        get
        {
            // This will create CDATA in address node. String values for
            // CDATA are in addresses collection.
            // This is causing problem.
            return new Collection<XmlNode>(addresses.Select(a => xmlDoc.CreateCDataSection(a)).ToArray());
        }
        set
        {
            // Set also address collection of string to the same values.
            addresses = new Collection<string>(value.Select(a => a.Value).ToArray());

            addressesNode = value;
        }
    }

    [XmlIgnore]
    public Collection<string> Addresses
    {
        get
        {
            return addresses;
        }
    }
}

序列化工作正常。但是在反序列化时,会抛出异常

 "Collection is read-only."

2 个答案:

答案 0 :(得分:0)

我认为您可能需要拨打ToList而不是ToArray

答案 1 :(得分:0)

当您创建一个将IList作为参数传递的新集合时,它会将集合创建为原始列表的包装器。它不会将其复制到新列表(请参阅here)。在您的addressNode setter中,您将创建一个新集合作为集合的包装器。您可以将其更改为新的List,因为List构造函数确实创建了一个新列表而不是包装原始列表(请参阅here)。