XML - 反序列化为对象

时间:2016-11-16 14:11:39

标签: c# asp.net xml web-services api

我正在尝试将API响应反序列化为对象,但对象仍然返回NULL。我无法弄明白。我觉得我错过了一些小事。

这里是c#反序列化代码。

<PICKUPREQUESTRESPONSE xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
<STATUS>
    <CODE>1</CODE>
    <VIEW>ERROR</VIEW>
    <ERRORTYPE>INPUT_ERROR</ERRORTYPE>
    <MESSAGE>Testing Mode: You have passed input validation, the pickup request has NOT been submitted</MESSAGE>
    <VERSION>
        <CURRENT>V3X1</CURRENT>
        <CURRENT_RELEASE_DATE>03/01/2014</CURRENT_RELEASE_DATE>
        <LATEST>V3X1</LATEST>
        <LATEST_RELEASE_DATE>03/01/2014</LATEST_RELEASE_DATE>
    </VERSION>
</STATUS>
</PICKUPREQUESTRESPONSE>

这是来自API的XML响应。

[Serializable()]
[System.Xml.Serialization.XmlRoot("PICKUPREQUESTRESPONSE")]
public class PICKUPREQUESTRESPONSE
{
    [XmlArray("PICKUPREQUESTRESPONSE")]
    [XmlArrayItem("STATUS", typeof(STATUS))]
    public STATUS[] STATUS { get; set; }
}


[Serializable()]
public class STATUS
{
    [XmlElement("CODE")]
    public string CODE { get; set; }

    [XmlElement("VIEW")]
    public string VIEW { get; set; }

    [XmlElement("ERRORTYPE")]
    public string ERRORTYPE { get; set; }

    [XmlElement("MESSAGE")]
    public string MESSAGE { get; set; }

    [XmlArrayItem("VERSION", typeof(VERSION))]
    public VERSION[] VERSION { get; set; }

}

[Serializable()]
public class VERSION
{
    [System.Xml.Serialization.XmlElement("CURRENT")]
    public string CURRENT { get; set; }

    [System.Xml.Serialization.XmlElement("CURRENT_RELEASE_DATE")]
    public string CURRENT_RELEASE_DATE { get; set; }

    [System.Xml.Serialization.XmlElement("LATEST")]
    public string LATEST { get; set; }

    [System.Xml.Serialization.XmlElement("LATEST_RELEASE_DATE")]
    public string LATEST_RELEASE_DATE { get; set; }

}

这是我创建的c#对象。

{{1}}

1 个答案:

答案 0 :(得分:1)

您的数据合同以错误的方式构建

public class PICKUPREQUESTRESPONSE
{
    [XmlArray("PICKUPREQUESTRESPONSE")]
    [XmlArrayItem("STATUS", typeof(STATUS))]
    public STATUS[] STATUS { get; set; }
}

这会假设您的xml看起来像这样

<?xml version="1.0" encoding="utf-16"?>
<PICKUPREQUESTRESPONSE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <PICKUPREQUESTRESPONSE>
    ...

VERSION也是如此。通过指定XmlArray和XmlArrayItem,它将期望样本xml没有的元素的嵌套实例。

以下对象应该有效

[Serializable()]
[System.Xml.Serialization.XmlRoot("PICKUPREQUESTRESPONSE")]
public class PICKUPREQUESTRESPONSE
{
    //[XmlArray("PICKUPREQUESTRESPONSE")]
    //[XmlArrayItem("STATUS", typeof(STATUS))]
    [XmlElement("STATUS")]
    public STATUS[] STATUS { get; set; }
}


[Serializable()]
public class STATUS
{
    [XmlElement("CODE")]
    public string CODE { get; set; }

    [XmlElement("VIEW")]
    public string VIEW { get; set; }

    [XmlElement("ERRORTYPE")]
    public string ERRORTYPE { get; set; }

    [XmlElement("MESSAGE")]
    public string MESSAGE { get; set; }

    //[XmlArrayItem("VERSION", typeof(VERSION))]
    [XmlElement("VERSION")]
    public VERSION[] VERSION { get; set; }

}

[Serializable()]
public class VERSION
{
    [System.Xml.Serialization.XmlElement("CURRENT")]
    public string CURRENT { get; set; }

    [System.Xml.Serialization.XmlElement("CURRENT_RELEASE_DATE")]
    public string CURRENT_RELEASE_DATE { get; set; }

    [System.Xml.Serialization.XmlElement("LATEST")]
    public string LATEST { get; set; }

    [System.Xml.Serialization.XmlElement("LATEST_RELEASE_DATE")]
    public string LATEST_RELEASE_DATE { get; set; }

}

我还建议使用xml序列化的标准模式,类似这样的

/// <summary>
/// Deserialize an xml string to type T
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xml"></param>
/// <returns></returns>
public static T Deserialize<T>(string xml)
{
    if (string.IsNullOrEmpty(xml))
        return default(T);

    XmlSerializer serializer = new XmlSerializer(typeof(T));

    XmlReaderSettings settings = new XmlReaderSettings();
    // No settings need modifying here

    using (StringReader textReader = new StringReader(xml))
    {
        using (XmlReader xmlReader = XmlReader.Create(textReader, settings))
        {
            return (T)serializer.Deserialize(xmlReader);
        }
    }
}

像这样调用

var resp = Deserialize<PICKUPREQUESTRESPONSE>(thexml);