programming with esskar

Just another WordPress.com weblog

JSONBuilder in C#

with one comment

Small JSON Builder (no garanty it will work for every object):

public sealed class JSONBuilder
{
    private List<object> m_objects = new List<object>();

    public void Append(object obj)
    {
        m_objects.Add(obj);
    }

    private static void EncodeAny(StringBuilder sb, object o)
    {
        if (o == null)
            sb.Append("null");
        else if (o is string || o is Enum || o is Guid || o is char)
            JSONBuilder.EncodeString(sb, o.ToString());
        else if (o is sbyte || o is byte || o is short || o is ushort || o is int || o is uint || o is long || o is ulong || o is decimal || o is double || o is float)
            sb.Append(Convert.ToString(o, System.Globalization.NumberFormatInfo.InvariantInfo));
        else if (o is bool)
            sb.Append(o.ToString().ToLower());
        else if (o is IDictionary)
            JSONBuilder.EncodePairs(sb, o as IDictionary);
        else if (o is Array || o is IList || o is ICollection)
            JSONBuilder.EncodeArray(sb, o as IEnumerable);
        else
            JSONBuilder.EncodeObject(sb, o);
    }

    private static void EncodeObject(StringBuilder sb, object o)
    {
        Type t = o.GetType();
        bool addComma = false;            

        sb.Append("{");            
        foreach (MemberInfo member in t.GetMembers())
        {
            if (member.MemberType != MemberTypes.Property) continue;
            PropertyInfo pi = t.GetProperty(member.Name);
            if (pi == null) continue;
            MethodInfo mi = pi.GetGetMethod();
            if (mi == null || pi.GetSetMethod() == null) continue; // we could serialize, but could not deserialize

            if (addComma) sb.Append(',');
            JSONBuilder.EncodePair(sb, member.Name, mi.Invoke(o, null));
            addComma = true;
        }
        sb.Append("}");
    }

    private static void EncodePair(StringBuilder sb, string s, object o)
    {
        JSONBuilder.EncodeString(sb, s);
        sb.Append(':');
        JSONBuilder.EncodeAny(sb, o);
    }

    private static void EncodeArray(StringBuilder sb, IEnumerable i)
    {
        sb.Append('[');
        bool addComma = false;
        foreach (object o in i)
        {
            if (addComma) sb.Append(',');
            JSONBuilder.EncodeAny(sb, o);
            addComma = true;
        }
        sb.Append(']');
    }

    private static void EncodePairs(StringBuilder sb, IDictionary i)
    {
        sb.Append('{');
        bool addComma = false;
        foreach (DictionaryEntry o in i)
        {
            if (addComma) sb.Append(',');
            JSONBuilder.EncodePair(sb, o.Key.ToString(), o.Value);
            addComma = true;
        }
        sb.Append('}');
    }

    private static void EncodeString(StringBuilder sb, string s)
    {
        sb.Append('"');
        foreach (char c in s)
        {
            switch (c)
            {
                case '\t': sb.Append("\\t"); break;
                case '\r': sb.Append("\\r"); break;
                case '\n': sb.Append("\\n"); break;
                case '"':
                case '\\': sb.Append("\\" + c); break;
                default: sb.Append(c >= ' ' && c < 128 ? c.ToString() : "\\u" + ((int)c).ToString("X4")); break;
            }
        }
        sb.Append('"');
    }

    public static string Build(object o)
    {
        JSONBuilder json = new JSONBuilder();
        json.Append(o);
        return json.ToString();
    }

    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        if (m_objects.Count == 0) JSONBuilder.EncodeAny(sb, null);
        else if (m_objects.Count == 1) JSONBuilder.EncodeAny(sb, m_objects[0]);
        else JSONBuilder.EncodeArray(sb, m_objects);
        return sb.ToString();
    }
}

I use it to store objects into the registry and still be able to edit the values there by hand.
An extension that helps me here is:
namespace System
{
    public static class ObjectExtension
    {
        public static string ToJSON(this object obj)
        {
            return JSONBuilder.Build(obj);
        }
    }
}

Next blog entry will be a JSON”Unbuilder” … :-) stay tuned.

Advertisement

Written by esskar

February 18, 2010 at 2:28 pm

One Response

Subscribe to comments with RSS.

  1. There’s already a json serializer in .net framework. Take a look to http://blogs.msdn.com/rakkimk/archive/2009/01/30/asp-net-json-serialization-and-deserialization.aspx

    bye ;)

    ivowiblo

    February 19, 2010 at 1:30 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.