CSharp · Console
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
using System.Diagnostics;
public static class XmlNodeExtensions
{
public static XmlDocument AsXmlDocument<T>(this T o, XmlSerializerNamespaces ns = null, XmlSerializer serializer = null)
{
XmlDocument doc = new XmlDocument();
using (XmlWriter writer = doc.CreateNavigator().AppendChild())
new XmlSerializer(o.GetType()).Serialize(writer, o, ns);
return doc;
}
public static XmlElement AsXmlElement<T>(this T o, XmlSerializerNamespaces ns = null, XmlSerializer serializer = null)
{
return o.AsXmlDocument(ns, serializer).DocumentElement;
}
public static T Deserialize<T>(this XmlElement element, XmlSerializer serializer = null)
{
using (var reader = new ProperXmlNodeReader(element))
return (T)(serializer ?? new XmlSerializer(typeof(T))).Deserialize(reader);
}
/// <summary>
/// Return an XmlSerializerNamespaces that disables the default xmlns:xsi and xmlns:xsd lines.
/// </summary>
/// <returns></returns>
public static XmlSerializerNamespaces NoStandardXmlNamespaces()
{
var ns = new XmlSerializerNamespaces();
ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
return ns;
}
}
public class ProperXmlNodeReader : XmlNodeReader
{
// Bug fix from http://stackoverflow.com/questions/30102275/deserialize-object-property-with-stringreader-vs-xmlnodereader
public ProperXmlNodeReader(XmlNode node)
: base(node)
{
}
public override string LookupNamespace(string prefix)
{
return NameTable.Add(base.LookupNamespace(prefix));
}
}
public partial class AppDataType
{
private System.Xml.XmlElement[] anyField;
private System.Xml.XmlAttribute[] anyAttrField;
/// <remarks/>
[System.Xml.Serialization.XmlAnyElementAttribute(Order = 1)]
public System.Xml.XmlElement[] Any
{
get
{
return this.anyField;
}
set
{
this.anyField = value;
}
}
[System.Xml.Serialization.XmlElement(Order = 0)]
public string TestValue { get; set; }
}
public class SomeRequestType
{
public string StringValue { get; set; }
public int[] IntList { get; set; }
}
public class TestClass
{
public static void Test()
{
try
{
TestInternal();
}
catch (Exception ex)
{
Debug.Assert(false, ex.ToString());
throw;
}
}
static void TestInternal()
{
var someRequestType = new SomeRequestType { StringValue = "string value", IntList = Enumerable.Range(0, 10).ToArray() };
var appDataType = new AppDataType
{
TestValue = "test value",
Any = new[] { someRequestType.AsXmlElement(XmlNodeExtensions.NoStandardXmlNamespaces()) },
};
var xml = appDataType.GetXml();
Console.WriteLine(xml);
var appDataBack = xml.LoadFromXML<AppDataType>();
if (!(appDataType.Any.Select(e => e.OuterXml).SequenceEqual(appDataBack.Any.Select(e => e.OuterXml))))
{
throw new InvalidOperationException("!(appDataType.Any.Select(e => e.OuterXml).SequenceEqual(appDataBack.Any.Select(e => e.OuterXml)))");
}
if (!someRequestType.IntList.SequenceEqual(appDataBack.Any[0].Deserialize<SomeRequestType>().IntList)
|| someRequestType.StringValue != appDataBack.Any[0].Deserialize<SomeRequestType>().StringValue)
{
throw new InvalidOperationException("!nested.IntList.SequenceEqual(appDataBack.Any[0].Deserialize<Nested>().IntList) || nested.StringValue != appDataBack.Any[0].Deserialize<Nested>().StringValue");
}
}
}
public static class XmlSerializationHelper
{
public static T LoadFromXML<T>(this string xmlString, XmlSerializer serializer = null)
{
T returnValue = default(T);
using (StringReader reader = new StringReader(xmlString))
{
object result = (serializer ?? new XmlSerializer(typeof(T))).Deserialize(reader);
if (result is T)
{
returnValue = (T)result;
}
}
return returnValue;
}
public static string GetXml<T>(this T obj, XmlSerializerNamespaces ns = null, XmlWriterSettings settings = null, XmlSerializer serializer = null)
{
using (var textWriter = new StringWriter())
{
settings = settings ?? new XmlWriterSettings() { Indent = true, IndentChars = " " }; // For cosmetic purposes.
using (var xmlWriter = XmlWriter.Create(textWriter, settings))
(serializer ?? new XmlSerializer(typeof(T))).Serialize(xmlWriter, obj, ns);
return textWriter.ToString();
}
}
}
public class Program
{
public static void Main()
{
TestClass.Test();
}
}