my6solutions

asp .net, the social web & other distractions

 

Running Apps


PayPal - The safer, easier way to pay online!

Disclaimer

I am in no way affiliated with Microsoft or Google. I am just another developer trying to make a difference. All opinions and observations are usually my own.

Custom JavaScriptConverter using Reflection for ASP.NET

Recently, I've realised that I have not implemented the deserialization methods for the OpenSocial API for pesta. I found out while trying to deserialize Google Friend Connect data. Oops. I guess my memory is not as good as it used to be.

I found out that the DataContractSerializer is not effective when some fields are missing in the JSON string. So I finally implemented the Deserialize method for a custom JavaScriptConverter for the JavaScriptSerializer. I couldn't find a good example from the net. But I didn't spend too long searching so I could have missed out.

Basically, it uses reflection to determine the field type and to set the value of the field. This is done recursively from the dictionary of field names and values. Known issue, it currently does not handle the case where the field type is a dictionary. Will do this later when needed.

public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)

{

    return ConvertToObject(dictionary, type);

}

 

public object ConvertToObject(IDictionary<string, object> dictionary, Type type)

{

    var obj = Activator.CreateInstance(type);

    foreach (var entry in dictionary)

    {

        var fieldType = type.GetProperty(entry.Key).PropertyType;

        var valueType = entry.Value.GetType();

        if (typeof(IDictionary).IsAssignableFrom(valueType))

        {

            ConvertToObject((IDictionary<string, object>)entry.Value, fieldType);

        }

        else

        {

            if (typeof(IList).IsAssignableFrom(fieldType))

            {

                Type argType = fieldType.GetGenericArguments()[0];

                var listObj = Activator.CreateInstance(fieldType);

                foreach (var val in (IList)entry.Value)

                {

                    ((IList)listObj).Add(ConvertToObject((IDictionary<string, object>)val, argType));

                }

            }

            else

            {

                type.GetProperty(entry.Key).SetValue(obj, entry.Value, null);

            }

        }

    }

    return obj;

}

 

To use the converter, you just need to specify it when instantiating the JavaScriptSerializer object like so

public override T ConvertToObject<T>(String json)

{

    var serializer = new JavaScriptSerializer();

    serializer.RegisterConverters(new JavaScriptConverter[] { new DataContractJSConverter() });

    return serializer.Deserialize<T>(json);

}

 

The entire custom JavaScriptConverter class is viewable here, http://code.google.com/p/pesta/source/browse/trunk/pesta/pesta/Engine/protocol/conversion/DataContractJSConverter.cs.

 

Bookmark and Share

Permalink | Comments (0) | Post RSSRSS comment feed