XmlSerializer没有反序列化int数组

时间:2014-12-11 13:38:03

标签: c# .net xml serialization xml-serialization

我有以下类型:

[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/MyNamespace")]
public class Location
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Collection<int> DataSourceIds { get; set; }
}

我将一个Locations列表序列化为XML,结果如下:

<ArrayOfLocation xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/MyNamespace">
    <Location>
        <DataSourceIds xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <d3p1:int>1</d3p1:int>
        </DataSourceIds>
        <Id>2</Id>
        <Name>First</Name>
    </Location>
    <Location>
        <DataSourceIds xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <d3p1:int>1</d3p1:int>
            <d3p1:int>2</d3p1:int>
            <d3p1:int>3</d3p1:int>
            <d3p1:int>4</d3p1:int>
        </DataSourceIds>
        <Id>1</Id>
        <Name>Second</Name>
    </Location>
</ArrayOfLocation>

然后我尝试按如下方式反序列化此XML:

        var rootAttribute = new XmlRootAttribute("ArrayOfLocation")
        {
            Namespace = "http://schemas.datacontract.org/2004/07/MyNamespace"
        };

        var serializer = new XmlSerializer(typeof(Location[]), rootAttribute);
        using (var xmlReader = XmlReader.Create(new StreamReader(response.GetResponseStream())))
        {
            locations = (Location[])serializer.Deserialize(xmlReader);
        }

这将返回一个Location对象列表,每个属性设置正确...除了DataSourceIds,它仍为空。为什么XmlSerializer不反序列化整数数组?

1 个答案:

答案 0 :(得分:0)

由于它是使用DataContractSerializer序列化的,因此您可以将其反序列化:

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/MyNamespace")]
public class Location
{
    [DataMember]
    public int Id { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public Collection<int> DataSourceIds { get; set; }
}

然后使用它:

        using (var xmlReader = XmlReader.Create(stream))
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(Location[]));
            var locations = (Location[])serializer.ReadObject(xmlReader);
            Debug.WriteLine(DataContractSerializerHelper.GetXml(locations, serializer)); // Debug check on re-serialization, remove when not needed.
        }

XmlRoot忽略DataContractSerializer声明。

最后,一个用于重新序列化为XML字符串的实用程序方法,用于调试目的:

public static class DataContractSerializerHelper
{
    private static MemoryStream GenerateStreamFromString(string value)
    {
        return new MemoryStream(Encoding.Unicode.GetBytes(value ?? ""));
    }

    public static string GetXml<T>(T obj, DataContractSerializer serializer) where T : class
    {
        using (var textWriter = new StringWriter())
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = "    "; // For cosmetic purposes.
            using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings))
            {
                serializer.WriteObject(xmlWriter, obj);
            }
            return textWriter.ToString();
        }
    }

    public static string GetXml<T>(T obj) where T : class
    {
        DataContractSerializer serializer = new DataContractSerializer(typeof(T));
        return GetXml(obj, serializer);
    }
}