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: C#.NET, XML, XML Serialization
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.