Doug Dawson
Doug Dawson

Reputation: 1273

Class not serializing as expected

I've been struggling with this all day. I done a lot of research, but I just can't seem to put it all together.

I have a XML response from a server like so:

<?xml version="1.0" ?>
<inboxRecords>
    <inboxRecord>
        <field1 />
        <field2 />
        <field3 />
    </inboxRecord>
    <inboxRecord>
        <field1 />
        <field2 />
        <field3 />
    </inboxRecord>
</inboxRecords>

I created the following code to represent the response. The intention is that I will de-serialize the response using the following:

[XmlRoot("inboxRecords")]
public sealed class QueueQueryResult
{
    public InboxRecord[] InboxRecords;

    public QueueQueryResult()
    {
        InboxRecords = null;
    }

    public sealed class InboxRecord
    {
        public string field1 { get; set; }
        public string field2 { get; set; }
        public string field3 { get; set; }
    }
}

The classes above are based on one of the numerous examples I found online. The problem is, when I serialize the class above (to confirm that it is correct), it comes out like this:

<?xml version="1.0" encoding="utf-16"?>
<inboxRecords>
  <InboxRecords>
    <InboxRecord>
      <field1>some value</field1>
    </InboxRecord>
    <InboxRecord>
      <field1>some value</field1>
    </InboxRecord>
  </InboxRecords>
</inboxRecords>

So, first problem, how do I get rid of the extra InboxRecords element? I only want the root to say that (with a small 'i'). Second, for quick testing, I only put a value in the first field. Why didn't the other fields come out as empty elements? Do I need another decorator for that?

Thanks! Thanks!

Upvotes: 2

Views: 102

Answers (3)

Jesse C. Slicer
Jesse C. Slicer

Reputation: 20157

After generating an XSD from your first sample XML (and then a .cs) using xsd.exe, I can create and serialize an instance from your second example:

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

With the exception of the encoding attribute and the schema namespace, this looks pretty darn similar to the first sample.

Upvotes: 0

gilly3
gilly3

Reputation: 91467

Use the XmlElement attribute:

[XmlRoot("inboxRecords")]
public sealed class QueueQueryResult
{
    [XmlElement("inboxRecord")]
    public InboxRecord[] InboxRecords;

    public QueueQueryResult()
    {
        InboxRecords = null;
    }

    public sealed class InboxRecord
    {
        public string field1 { get; set; }
        public string field2 { get; set; }
        public string field3 { get; set; }
    }
}

This removes the Array wrapper element and allows you to control the name for each xml element so that you can use lower case names.

Upvotes: 3

Fabian Tamp
Fabian Tamp

Reputation: 4516

Untested, but I reckon you could probably do something like this:

[XmlRoot("inboxRecords")]
public sealed class QueueQueryResult : Collection<QueueQueryResult.InboxRecord>
{
    public QueueQueryResult()
    {
        InboxRecords = null;
    }

    public sealed class InboxRecord
    {
        public string field1 { get; set; }
        public string field2 { get; set; }
        public string field3 { get; set; }
    }
}

The problem with your code is that you've got a member InboxRecords within an object that is serialising to inboxRecords. By making the class inherit from Collection, you're providing it with the capability to handle a set of InboxRecords without the extra inner element.

Upvotes: 1

Related Questions