Hi, I'm Ray

23 Feb, 2019

C#: Serialise object to XML (three flavours)

Programming, .NET, C#

I feel like at some point in every project you find yourself needing to serialise an object. My immediate go-to is JSON: whether it’s being send to another system or saved to disk, the magicians at Newtonsoft have made it super-easy with JSON. However, when I had a requirement to use XML (because I’d be damned to use CSV), the results looked somewhat messier than I expected.

Here’s what I discovered when serialising an object to XML, in three flavours.

Let’s get started.

0. Setup

This is the demo class I’m using for testing.

using Newtonsoft.Json;

public class ClassA
  public int Prop1 { get; set; }

  public string Prop2 { get; set; }

  public int? Prop3 { get; set; }

  public bool Prop4 { get; set; }

ClassA ob = new ClassA() {
  Prop1 = 200,
  Prop2 = "hello world",
  Prop3 = null,
  Prop4 = true


1. Vanilla (aka XmlSerializer)

This is the textbook answer using XmlSerializer.

protected string serialiseToXML(Type type, object ob)
  StringWriter sw = new StringWriter();

  XmlSerializer xsz = new XmlSerializer(type);
  xsz.Serialize(sw, ob);

  return sw.ToString();

The result is good but has lengthy namespace attributes.

<?xml version="1.0" encoding="utf-16"?>
<ClassA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Prop2>hello world</Prop2>
  <Prop3 xsi:nil="true" />


2. Banana (aka XmlSerializer with Namespace)

This is what you find all over the Web when you want to hide the xmlns.

protected string serialiseToXMLNS(Type type, object ob)
  StringWriter sw = new StringWriter();

  XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
  ns.Add("", "");

  XmlSerializer xsz = new XmlSerializer(type);
  xsz.Serialize(sw, ob, ns);

  return sw.ToString();

The result is good but I still see namespaces.

<?xml version="1.0" encoding="utf-16"?>
  <Prop2>hello world</Prop2>
  <Prop3 d2p1:nil="true" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance" />


3. Chocolate (aka JsonConvert)

This is a solution some idiot came up with by serialising the object to JSON and then to XML. There’s an added step because XML expects a single root node.

protected string serialiseToXMLByJSON(Type type, object ob)
  object newOb = new { root = ob };
  string rv = JsonConvert.SerializeObject(newOb);

  XmlDocument doc = JsonConvert.DeserializeXmlNode(rv);
  return string.Concat("<", type.Name , ">", doc.FirstChild.InnerXml, "</", type.Name, ">");

The result is minimised.

<ClassA><Prop1>200</Prop1><Prop2>hello world</Prop2><Prop3 /><Prop4>true</Prop4></ClassA>


A. Deserialise for (1) and (2)

I didn’t want to show code for serialising an object to XML without including code to deserialise back to the object.

StringReader sr = new StringReader(xml);
XmlSerializer xsz = new XmlSerializer(typeof(ClassA));
ClassA ob = (ClassA)xsz.Deserialize(sr);


B. Deserialise for (3)

Remember that root node that XML needs? Yes, we have to handle that when deserialising the XML to JSON then to object.

protected ClassA deserialiseXMLJSONObject(string xml)
  XmlDocument doc = new XmlDocument();

  // remove root node
  string json = JsonConvert.SerializeXmlNode(doc.FirstChild);
  int n = json.IndexOf(":") + 1;

  json = json.Substring(n, (json.Length - n - 1));

  return JsonConvert.DeserializeObject<ClassA>(json);


I hope someone finds this useful.