1

I have an XML structure like this:

<QueryResult>
    <Submission>
        <Sections>
            <Section>
                <!--Section Data-->
            </Section>
        </Sections>
    </Submission>
</QueryResult>

I am trying to deserialize - I never have to serialize - this to a Submission object, e.g:

public partial class Submission : CanvasModel
{
    private DateTime _date;
    private DateTime _deviceDate;
    private List<Section> _sections = new List<Section>();

    [XmlIgnore]
    public ICollection<Section> Sections
    {
        get
        {
            return _sections;
        }
        set
        {
            _sections = value.ToList();
        }
    }

    //[XmlArrayItem("Section", IsNullable = false)]
    [XmlArrayItem(typeof(Section), ElementName = "Sections", IsNullable = false)]
    public Section[] SectionsArray
    {
        get
        {
            return _sections.ToArray();
        }
        set
        {
            _sections = new List<Section>(value);
        }
    }
}

Yet the XML element Sections is not deserializing. It only works when the Section[] property has the same name as the XML element, Sections. I am wrestling with the XmlArrayItem attribute and am losing. Elsewhere when the names differ, I use the XmlElement attribute to specify the element name, and everything works fine. However, I am not allowed to use XmlElement and XmlArrayItem on the same property.

What is the correct way for me to use the XmlArrayItem attribute to deserialize the Sections XML element to the SectionsArray property?

BTW, I want the widely used property, public ICollection<Section> Sections, that I need for my EF data model, to have the document name, Sections, for several reasons, so just swapping the two names is really my last resort. I want to keep the current SectionsArray property purely for deserialization.

2 Answers 2

4

There would be two ways to get around this by using xml serialization attributes.

First is AncientSyntax's answer which I agree with, with the sole amendment that you have to specify node name explicitly for the array.

    [XmlRootAttribute( "Submission", Namespace = "", IsNullable = false)]
    public class Submission : CanvasModel { 
        private List<Section> _sections = new List<Section>();

    [XmlIgnore]
    public virtual ICollection<Section> Sections
    {
        get { return _sections; }
        set { _sections = value.ToList(); }
    }

    [XmlArray(ElementName="Sections")]
    [XmlArrayItem("Section", IsNullable = false)]
    public Section[] SectionsArray
    {
        get { return _sections.ToArray(); }
        set { _sections = value.ToList(); }
    }
    }

The less straightforward way is to wrap your array into an intermediate type like:

[SerializableAttribute()]
[XmlRootAttribute("Sections", Namespace = "", IsNullable = false)]
public partial class Sections {
    private Section[] sectionField;
    [XmlElementAttribute("Section")]
    public Section[] Section
    {
      get { return this.sectionField; }
      set { this.sectionField = value; }
    }
  }

and use it instead of the sections array:

private Sections _sectionsArrayWrapper;
[XmlElement(typeof(Sections), ElementName = "Sections", IsNullable = false)]    
public Sections SectionsArrayWrapper
{
      // your job to go from array wrapper to collection
}

Both definitions work with:

[SerializableAttribute()]
[XmlRootAttribute("Section", Namespace = "", IsNullable = false)]
public class Section { }

and public class CanvasModel { }

This was tested with the xml you provided.

Sign up to request clarification or add additional context in comments.

1 Comment

And we have a winner! Adding the array element name did it.
3

The ElementName should be the name of the contained xml element, in this case Section.

In addition it looks like you should be using XmlArrayAttribute as well as an XmlArrayItemAttribute.

[XmlArray]
[XmlArrayItem(typeof(Section), ElementName = "Section", IsNullable = false)]

See http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlarrayattribute%28v=vs.110%29.aspx for an example.

1 Comment

Adding XmlArrayAttribute seems to make no difference. If the class name differs from the element name, I still get zero Sections in all cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.