XML Serialization and List

I was writing a small wrapper class to consume a third party XML response from a web service. Using a little helper class is a lot easier than playing with DOM. One of the elements was an Errors element that could have multiple Error child elements, like so:


<Errors>
   <Error>detail</Error>
   <Error>detail</Error>
</Errors>

In my class, I wanted to use a List<string> to account for this, but since I was consuming XML, I needed to be able to tell it the element name, otherwise it serializes and deserializes as just “string”, like this.


<?xml version="1.0" encoding="utf-16"?>
<WebServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<statusCode>failure</statusCode>
<recordsAffected>0</recordsAffected>
<Errors>
   <string>Foo</string>
</Errors>
</WebServiceResponse>

 

So when I tried to read in the xml, I got an error because it couldn’t find an Error element (it was string). Not so helpful.

I needed the ElementName property in my class.

[XmlArrayItem(typeof(string), ElementName = "Error")]
public List<string> Errors;

Adding this, the element was correctly deserialized so it could read something like this.


<?xml version="1.0" encoding="utf-16"?>
<WebServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<statusCode>failure</statusCode>
<recordsAffected>0</recordsAffected>
<Errors>
   <Error>Foo</Error>
</Errors>
</WebServiceResponse>

Here is some code to play with so you can try it out and see how the attribute affects serialization and deserialization. Have fun!


using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using System.Text;

namespace ConsoleApplication1
{
    public class Program
    {
        public class WebServiceResponse
        {
            public string statusCode;
            public string recordsAffected;

            [XmlArrayItem(typeof(string), ElementName = "Error")]
            public List<string> Errors;
        }

        static void Main(string[] args)
        {
            // if we were to set the elements themselves, it could look like this
            WebServiceResponse r = new WebServiceResponse();
            r.statusCode = "success";
            r.recordsAffected = "1";
            r.Errors = new List<string>();
            r.Errors.Add("Foo");

            XmlSerializer serializer = new XmlSerializer(typeof(WebServiceResponse));
            StringBuilder sb = new StringBuilder();
            serializer.Serialize(new StringWriter(sb), r);
            Console.WriteLine(sb.ToString());

            string s = sb.ToString();
            // more likely, we'd be reading them in from an XML response to manipulate, like so
            // (you'd have the xml response from a web service in a string or such)
            TextReader sr = new StringReader(s);
            WebServiceResponse r2 = serializer.Deserialize(sr) as WebServiceResponse;
            int numErrors = r2.Errors == null ? 0 : r2.Errors.Count;
            Console.WriteLine("There were " + numErrors + " errors");

            Console.Read();
        }
    }
}

Tags: , ,

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply