Mike_G
Mike_G

Reputation: 16502

Error deserializing xml web response

I am trying to deserialize a "SearchRecordList" class using the DataContractSerializer and keep getting the exception:

System.InvalidOperationException: No corresponding start element is open.

The XML i am receiving looks like this:

<?xml version=\"1.0\" encoding=\"UTF-8\"?><records type=\"array\" count=\"0\"/>

What is strange, is that if i run a test, and pass this XML string:

<?xml version=\"1.0\" encoding=\"UTF-8\"?><records type=\"array\" count=\"0\"></records>

It works fine. Any ideas what I am doing wrong? Below is the class I am deserializing to (C#, .NET 4.0):

 [XmlRoot(Namespace = "", ElementName = "records", DataType = "array")]
public class SearchRecordList:List<SearchRecord>, IXmlSerializable
{

    #region IXmlSerializable Members

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        var navigator = reader.CreateNavigator(); //returns an XPathNavigator based on the reader.
        var root = navigator.SelectSingleNode("records");

        int count;

        if (!int.TryParse(root.GetAttribute("count", ""), out count) || count < 1)
            return;

        navigator.MoveToFirstChild();

        var n = navigator.Select("record");

        AddRange(n.ToList<SearchRecord>());
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        throw new System.NotImplementedException();
    }

    #endregion
}

Upvotes: 1

Views: 2011

Answers (2)

rsbarro
rsbarro

Reputation: 27339

In my opinion, the DataContractSerializer should only be used to deserialize data that was serialized using the DataContractSerializer. It's just not as flexible as something like XmlSerializer. For example, the DataContractSerializer expects all XML elements to be in alphabetical order when it deserializes (see the accepted answer here: WCF web service Data Members defaulting to null). How can you guarantee that the web service you are calling is going to adhere to this requirement? To put it another way, the DataContractSerializer is not a general purpose XML deserializer, it expects data in a very specific format. To the DataContractSerializer, <records></records> and <records /> are not equivalent.

If the data you are consuming is coming from a web service, you probably should just call the web service by setting up a Service Reference. If you don't want to do that, then I would use XmlSerializer. It doesn't sound like DataContractSerializer is the right class to use in this instance.

Upvotes: 2

Ed Charbeneau
Ed Charbeneau

Reputation: 4634

If XPath is giving you trouble you could use LINQ to XML instead. Since LINQ is not a forward-only parser, it can parse the document with out needing to know too much about its structure. http://msdn.microsoft.com/en-us/library/bb387061.aspx

Upvotes: 0

Related Questions