2

Dictionary シリアライゼーションの XML をよりクリーンにするために、 を実装するカスタム クラスを作成しIXmlSerializableました。

私のカスタムクラスは次のように定義されています:

public class MyCollection : System.Collections.Generic.Dictionary<string, string>, IXmlSerializable
{
    private const string XmlElementName = "MyData";
    private const string XmlAttributeId = "Id";

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        reader.MoveToContent();
        while (reader.Read())
        {
            if(reader.LocalName == XmlElementName)
            {
                var tag = reader.GetAttribute(XmlAttributeId);
                var content = reader.ReadElementContentAsString(); 

                this.Add(tag, content);
            }
        }
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        foreach (string key in this.Keys)
        {
            writer.WriteStartElement(XmlElementName);
            writer.WriteAttributeString(XmlAttributeId, key);
            writer.WriteString(this[key]);
            writer.WriteEndElement();
        }
    }
}

私のコードは、次の XML スニペットで動作します。

<MyCollection xmlns="http://schemas.datacontract.org/2004/07/MyProject" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <MyData Id="1">some content</MyData>
    <MyData Id="2">some other content</MyData>
</MyCollection>

ただし、この縮小された XML がある場合、私のコードは例外をスローします。

<MyCollection xmlns="http://schemas.datacontract.org/2004/07/MyProject" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><MyData Id="1">some content </MyData><MyData Id="2">some other content</MyData></MyCollection>

例外は次のとおりです。

System.InvalidOperationException: The ReadElementContentAsString method is not supported on node type EndElement

への呼び出しでスローされReadElementContentAsStringます。

コードを修正するにはどうすればよいですか?

次を使用して問題を再現できます。

var xml = @"<MyCollection xmlns=""http://schemas.datacontract.org/2004/07/MyProject"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""><MyData Id=""1"">some content </MyData><MyData Id=""2"">some other content</MyData></MyCollection>";

var raw = Encoding.UTF8.GetBytes(xml);

var serializer = new DataContractSerializer(typeof(MyCollection));

using (var ms = new MemoryStream(raw))
{
    var result = serializer.ReadObject(ms); // Exception throws here
}
4

1 に答える 1