Home > Software design >  Deserializing XmlArrayItemAttribute to PascalCase property is Null
Deserializing XmlArrayItemAttribute to PascalCase property is Null

Time:05-20

I am consuming a 3rd party XML API and have copied a postman response from the API and "Pasted XML As Classes" from the result into visual studio. This gives me an object with the following property:


    // NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
    public partial class forum : ItemBase
    {

        private forumThread[] threadsField;

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayItemAttribute("thread", IsNullable = false)]
        public forumThread[] threads
        {
            get
            {
                return this.threadsField;
            }
            set
            {
                this.threadsField = value;
            }
        }
    }

This deserializes just fine and captures all the data. I'd like to clean up this generated code a bit however, For example I want to rename the property name, as well as the forumList class to follow C# PascalCase conventions. So I would like to rename threads to Threads and forumThread to ForumThread. With other attributes/properties I've been successful at doing this by adding a name to the attribute but that doesn't work in this case, when I change the generated code to this, for example:

[XmlArrayItem("thread", ElementName = "threads", IsNullable = false)]
public forumThread[] Threads {get; set;}

It deserializes to null every time and looses the data from the API call. Any help on this would be greatly appreciated.

The class that deserializes the object is here:

public T Deserialize<T>(string xml) 
            where T : ItemBase
        {
            if (string.IsNullOrWhiteSpace(xml))
            {
                return null;
            }

            using var stringReader = new StringReader(xml);

            var serializer = new XmlSerializer(typeof(T));            
            var xmlReader = new XmlTextReader(stringReader);

            return (T)serializer.Deserialize(xmlReader);
        }

And a sample of the xml we are deserializing:

<forum id="3" title="Testing Forum" numthreads="1816" numposts="13685" lastpostdate="Thu, 01 Jan 1970 00:00:00  0000" noposting="0" termsofuse="https://boardgamegeek.com/xmlapi/termsofuse">
    <threads>
        <thread id="568813" subject="test thread" author="dakarp" numarticles="16" postdate="Tue, 28 Sep 2010 05:59:08  0000" lastpostdate="Sat, 02 Apr 2022 11:57:08  0000" />
        <thread id="1848343" subject="Test" author="Grafin" numarticles="1195" postdate="Thu, 14 Sep 2017 05:14:46  0000" lastpostdate="Sun, 15 May 2022 13:39:34  0000" />
   </threads>
</forum>

CodePudding user response:

The following resolved the issue and appears to be the required attributes to get it to deserialize correctly. I'm not very clear on what the generated code was doing to achieve the same result, but this has solidified my preference of JSON over xml

    [XmlArray("threads")]
    [XmlArrayItem("thread")]
    public forumThread[] Threads { get; set; }
  • Related