Is there a way in .NET 2.0 (C#) to serialize object like you do using XmlSerializer in a simple / customizable human readable format thats for instance looks like PXLS or JSON? Also I know that XML is human readable, I'm looking for something with less annoying redundancy, something that you can output to the console as a result for the user.
5 Answers
To Serialize into JSON in .NET you do as follows:
public static string ToJson(IEnumerable collection)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(collection.GetType());
string json;
using (MemoryStream m = new MemoryStream())
{
XmlDictionaryWriter writer = JsonReaderWriterFactory.CreateJsonWriter(m);
ser.WriteObject(m, collection);
writer.Flush();
json = Encoding.Default.GetString(m.ToArray());
}
return json;
}
The collections item need to have the "DataContract" attribute, and each member you wish to be serialized into the JSON must have the "DataMember" attibute.
It's possible that this only works for .NET 3.5. But there is an equally simple version for 2.0 aswell...

- 2,469
- 1
- 19
- 28
-
Some minutes ago by using [Json.NET](http://www.codeplex.com/Json) I found out that JSON is not the best way to do it since it did not support Enums. The result is a number that is not very human readable aswell. – Martin Nov 03 '08 at 15:10
-
Okej, well the implementation all depends on what you are serializing.. If it's only one type with few members why not just override "ToString" and return a string.Format in whatever format you'd like – ullmark Nov 03 '08 at 15:31
I found a exaustive documentation here:
with this usefull class (support generics)
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
public class JSONHelper
{
public static string Serialize<T>(T obj)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, obj);
string retVal = Encoding.Default.GetString(ms.ToArray());
ms.Dispose();
return retVal;
}
public static T Deserialize<T>(string json)
{
T obj = Activator.CreateInstance<T>();
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
obj = (T)serializer.ReadObject(ms);
ms.Close();
ms.Dispose();
return obj;
}
}

- 306
- 2
- 8
-
Using `Encoding.Default` doesn't work for non-ASCII text because the (undocumented) implementation of `DataContractJsonSerializer.WriteObject` uses hardcoded `Encoding.UTF8`. – mrexodia Nov 02 '16 at 18:57
The built-in serialization options for .Net are Xml, Xml-Soap, and binary. Since you've ruled out xml and binary is definitely not human readable, you'll have to roll your own.
When rolling your own, you have a few options:
- Add Utility or Extention methods to the class, like AviewAnew suggested
- Extend System.Runtime.Serialization.Formatter / Implement System.Runtime.Serialization.IFormatter
- Find a generic component online via google that will do what you want.
Note that the 2nd item can be specialized for your specific class (it doesn't have to be able to handle any class, if you don't want it to) and the latter two items are not mutually exclusive.
I have searched for a .Net JSON formatter in the past, and there are definitely multiple options out there. However, I ended up going a different direction that time. I just didn't feel very confident in any of them. Maybe someone else can provide a more specific recommendation. JSON is becoming big enough that hopefully Microsoft will include "native" support for it in the framework soon.

- 399,467
- 113
- 570
- 794
-
I could write my own HumanSerializer that is reflecting the type of object that were given to it - but this would consume way too much time. I thought that there already could be someone who solved this problem before - but google didn't find him or her. – Martin Nov 03 '08 at 14:59
https://stackoverflow.com/a/38538454/6627992
You may use following standard method for getting formatted Json
JsonReaderWriterFactory.CreateJsonWriter(Stream stream, Encoding encoding, bool ownsStream, bool indent, string indentChars)
Only set "indent==true"
Try something like this
public readonly DataContractJsonSerializerSettings Settings =
new DataContractJsonSerializerSettings
{ UseSimpleDictionaryFormat = true };
public void Keep<TValue>(TValue item, string path)
{
try
{
using (var stream = File.Open(path, FileMode.Create))
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
try
{
using (var writer = JsonReaderWriterFactory.CreateJsonWriter(
stream, Encoding.UTF8, true, true, " "))
{
var serializer = new DataContractJsonSerializer(type, Settings);
serializer.WriteObject(writer, item);
writer.Flush();
}
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
}
finally
{
Thread.CurrentThread.CurrentCulture = currentCulture;
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
}
}
Pay your attention to lines
var currentCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
....
Thread.CurrentThread.CurrentCulture = currentCulture;
You should use InvariantCulture to avoid exception during deserialization on the computers with different Regional settings. For example, invalid format of double or DateTime sometimes cause them.
For deserializing
public TValue Revive<TValue>(string path, params object[] constructorArgs)
{
try
{
using (var stream = File.OpenRead(path))
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
try
{
var serializer = new DataContractJsonSerializer(type, Settings);
var item = (TValue) serializer.ReadObject(stream);
if (Equals(item, null)) throw new Exception();
return item;
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
return (TValue) Activator.CreateInstance(type, constructorArgs);
}
finally
{
Thread.CurrentThread.CurrentCulture = currentCulture;
}
}
}
catch
{
return (TValue) Activator.CreateInstance(typeof (TValue), constructorArgs);
}
}
Thanks!
Apply a xsl to your xml to strip out what you don't want to see ?
something like
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" indent="yes"/>
<xsl:template match="*">
<xsl:value-of select="name()" /><xsl:text>
</xsl:text>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="@*|text()|comment()|processing-instruction">
<xsl:value-of select="name()" />:<xsl:value-of select="." /><xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>

- 1,547
- 4
- 19
- 34