The answer below handles IEnumerables in the form I needed and will do the following:
new { Foo = new[] { new { Name = "One" }, new { Name = "Two" }, }, Bar = new[] { new { Name = "Three" }, new { Name = "Four" }, }, }
in it:
<object> <Foo><Name>One</Name></Foo> <Foo><Name>Two</Name></Foo> <Bar><Name>Three</Name></Bar> <Bar><Name>Four</Name></Bar> </object>
So, here you are, another version of Matthew's answer:
public static class Tools { private static readonly Type[] WriteTypes = new[] { typeof(string), typeof(Enum), typeof(DateTime), typeof(DateTime?), typeof(DateTimeOffset), typeof(DateTimeOffset?), typeof(int), typeof(int?), typeof(decimal), typeof(decimal?), typeof(Guid), typeof(Guid?), }; public static bool IsSimpleType(this Type type) { return type.IsPrimitive || WriteTypes.Contains(type); } public static object ToXml(this object input) { return input.ToXml(null); } public static object ToXml(this object input, string element) { if (input == null) return null; if (string.IsNullOrEmpty(element)) element = "object"; element = XmlConvert.EncodeName(element); var ret = new XElement(element); if (input != null) { var type = input.GetType(); if (input is IEnumerable && !type.IsSimpleType()) { var elements = (input as IEnumerable<object>) .Select(m => m.ToXml(element)) .ToArray(); return elements; } else { var props = type.GetProperties(); var elements = from prop in props let name = XmlConvert.EncodeName(prop.Name) let val = prop.GetValue(input, null) let value = prop.PropertyType.IsSimpleType() ? new XElement(name, val) : val.ToXml(name) where value != null select value; ret.Add(elements); } } return ret; } }
Jeremy Cook Mar 16 '16 at 10:25 2016-03-16 22:25
source share