【问题标题】:XmlSerializer not deserializing int arrayXmlSerializer 不反序列化 int 数组
【发布时间】:2015-02-10 00:22:47
【问题描述】:

我有以下类型:

[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; }
}

我将位置列表序列化为 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 不对整数数组进行反序列化?

【问题讨论】:

  • 能发下序列化代码吗?
  • ASP.NET Web Api 负责序列化。
  • 虽然我刚刚意识到 Web API 默认使用 DataContractSerializer,所以这可能是问题的一部分...

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


【解决方案1】:

由于它是用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);
    }
}

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多