Skip to content

Instantly share code, notes, and snippets.

@danielcrenna
Created October 2, 2012 20:15
Show Gist options
  • Save danielcrenna/3823014 to your computer and use it in GitHub Desktop.
Save danielcrenna/3823014 to your computer and use it in GitHub Desktop.
Format XML media as plainly as possible
public class XmlFormatter : MediaTypeFormatter
{
private static readonly IDictionary<Type, XmlSerializer> Cache;
private static readonly XmlSerializerNamespaces IgnoreNamespaces;
static XmlFormatter()
{
Cache = new Dictionary<Type, XmlSerializer>();
IgnoreNamespaces = new XmlSerializerNamespaces();
IgnoreNamespaces.Add("", "");
}
public XmlFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
SupportedEncodings.Add(new UTF8Encoding(false, true));
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
return Task.Factory.StartNew(() => DeserializeFromStream(type, readStream));
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
return Task.Factory.StartNew(() => SerializeToStream(type, value, writeStream));
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public static Stream SerializeToStream(Type type, object instance, Stream stream)
{
var serializer = GetOrCreateSerializer(type);
var streamWriter = new StreamWriter(stream);
var writer = new IgnoreXmlDeclarationWriter(streamWriter);
serializer.Serialize(writer, instance, IgnoreNamespaces);
return stream;
}
public static object DeserializeFromStream(Type type, Stream stream)
{
var serializer = GetOrCreateSerializer(type);
var streamReader = new StreamReader(stream);
var reader = new IgnoreNamespacesReader(streamReader);
var instance = serializer.Deserialize(reader);
return instance;
}
private static XmlSerializer GetOrCreateSerializer(Type type)
{
XmlSerializer serializer;
if (!Cache.TryGetValue(type, out serializer))
{
serializer = new XmlSerializer(type);
Cache.Add(type, serializer);
}
return serializer;
}
private class IgnoreXmlDeclarationWriter : XmlTextWriter
{
public IgnoreXmlDeclarationWriter(TextWriter w) : base(w) { Formatting = Formatting.Indented; }
public override void WriteStartDocument()
{
}
private static string CamelCase(string name)
{
if (string.IsNullOrWhiteSpace(name)) return name;
if (char.IsLower(name[0])) return name;
if (name.Length == 1) return name.ToLower();
var letters = name.ToCharArray();
letters[0] = char.ToLower(letters[0]);
return new string(letters);
}
public override void WriteQualifiedName(string localName, string ns)
{
base.WriteQualifiedName(CamelCase(localName), ns);
}
public override void WriteStartAttribute(string prefix, string localName, string ns)
{
base.WriteStartAttribute(prefix, CamelCase(localName), ns);
}
public override void WriteStartElement(string prefix, string localName, string ns)
{
base.WriteStartElement(prefix, CamelCase(localName), ns);
}
}
private class IgnoreNamespacesReader : XmlTextReader
{
public IgnoreNamespacesReader(TextReader reader)
: base(reader)
{
}
public override string NamespaceURI
{
get { return string.Empty; }
}
}
}
@Lechus
Copy link

Lechus commented Mar 7, 2017

How to set OmitXmlDeclaration to false?
public override void WriteStartDocument()
{
// add this
base.WriteStartDocument(false);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment