PaymentDetails未成功反序列化,返回一个null对象,因为它似乎有IXmlDeserializable

时间:2014-02-24 22:23:10

标签: c# xmlserializer ixmlserializable

[XmlRoot("Quote")]
public class Quote
{
    [XmlElement("Insurance")]
    public InsuranceDetails InsDetails { get; set; }
    [XmlElement("Payment")]
    public PaymentDetails PayDetails { get; set; }
}

public class InsuranceDetails : IXmlSerializable
{
    [XmlElement(ElementName = "Details1")]
    public string Details1 { get; set; }

    public void ReadXml(XmlReader reader)
    {
            reader.ReadStartElement("Insurance");
               Details1 = reader.ReadElementString("Details1");
            reader.ReadEndElement();
    }
    public void WriteXml(XmlWriter writer)
    {
        // do write suff
    }
}

public class PaymentDetails
{
    [XmlElement(ElementName = "Details1")]
    public string Details1 { get; set; }
}

鉴于此示例,使用XmlSerializer将我的字符串反序列化为QuoteObject,PaymentDetails未成功反序列化,返回null对象,因为它似乎应该具有IXmlDeserializable。它只适用于首先解析PaymentDetails的情况。这是XmlSerializer的一些预期行为吗?

using (TextReader read = new StringReader(xml))
{
    var serializer = new XmlSerializer(typeof(Quote));
    return (Quote)serializer.Deserialize(read);
}

2 个答案:

答案 0 :(得分:1)

这些是我修改的ReadXmlWriteXml

 public void ReadXml(XmlReader reader)
 {
    reader.MoveToContent();
    var empty=reader.IsEmptyElement;
    reader.ReadStartElement();
    if(!empty){
        Details1=reader.ReadElementString("Details1");
        reader.ReadEndElement();
    }
}
public void WriteXml(XmlWriter writer)
{
    var str=string.IsNullOrWhiteSpace(Details1)?"":Details1;            
    writer.WriteElementString("Details1",str);
}

以下是序列化和反序列化函数:

public static string Serialize<T>(T t)
{
    var xmlser=new XmlSerializer(typeof(T));    
    XmlWriterSettings settings = new XmlWriterSettings();

    using(StringWriter textWriter = new StringWriter()) {
        using(XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings)) {
            xmlser.Serialize(xmlWriter, t);
        }
        return textWriter.ToString();
    }
}

public static T Deserialize<T>(string xml) 
{
     if(string.IsNullOrEmpty(xml)) {
        return default(T);
    }

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

    XmlReaderSettings settings = new XmlReaderSettings();

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

序列化测试:

var q=new Quote();
q.PayDetails = new PaymentDetails{Details1="Payment Details 1"};
q.InsDetails=new InsuranceDetails{Details1="Insurance Details 1"};  

str = Serialize<Quote>(q);

给出(str):

<?xml version="1.0" encoding="utf-16"?>
<Quote xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Payment>
        <Details1>Payment Details 1</Details1>
    </Payment>
    <Insurance>
        <Details1>Insurance Details 1</Details1>
    </Insurance>
</Quote>

反序列化测试:

var dq=Deserialize<Quote>(str);

Console.WriteLine(dq.PaymentDetails.Detail1);//gives "Payment Details 1"
Console.WriteLine(dq.InsuranceDetails.Detail1);//gives "Insurance Details 1"

PS: - Serialize代码是从另一个SO答案中逐字复制的。我学会了如何使用StringWriter序列化为字符串。

答案 1 :(得分:1)

首先,您不必在任何类中实现IXmlSerializable。其次,您不提供xml变量的内容。如果您手动创建,它可能包含错误/错误。

我使用以下代码来测试你的类:

using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace XmlDeSerialize
{
    [XmlRoot("Quote")]
    public class Quote
    {
        [XmlElement("Insurance")]
        public InsuranceDetails InsDetails { get; set; }
        [XmlElement("Payment")]
        public PaymentDetails PayDetails { get; set; }
    }
    public class InsuranceDetails
    {
        [XmlElement(ElementName = "Details1")]
        public string Details1 { get; set; }
    }
    public class PaymentDetails
    {
        [XmlElement(ElementName = "Details1")]
        public string Details1 { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var qin = new Quote
            {
                InsDetails = new InsuranceDetails { Details1 = "insurance details text" },
                PayDetails = new PaymentDetails { Details1 = "payment details text" },
            };

            string xml;
            using (var stream = new MemoryStream())
            {
                var serializer = new XmlSerializer(typeof(Quote));
                serializer.Serialize(stream, qin);
                stream.Position = 0;
                using (var sr = new StreamReader(stream))
                {
                    xml = sr.ReadToEnd();
                }
            }

            Quote qout;
            using (TextReader read = new StringReader(xml))
            {
                var deserializer = new XmlSerializer(typeof(Quote));
                var obj = deserializer.Deserialize(read);
                qout = (Quote)obj;
            }
            Console.WriteLine("InsDetails.Details1='{0}'", qout.InsDetails.Details1);
            Console.WriteLine("PayDetails.Details1='{0}'", qout.PayDetails.Details1);
        }
    }
}

序列化后xml的值:

<?xml version="1.0"?>
<Quote xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Insurance>
        <Details1>insurance details text</Details1>
    </Insurance>
    <Payment>
        <Details1>payment details text</Details1>
    </Payment>
</Quote>

我收到的控制台输出:

InsDetails.Details1='insurance details text'
PayDetails.Details1='payment details text'

亲自尝试代码,看看它是否适合您。很明显,对于我来说,你没有为反序列化提供有效的XML内容,或者你的问题中未提供的代码的其他部分应该受到责备。