Archive for September, 2011

Fighting ExtensionDataObject with JavaScriptSerializer for fun and profit

No Comments »

I guess the title is a little misleading because there is seldom any fun to be had with the .NET Framework.

But if you've got a Linq to SQL *.dbml and the tool is generating those swell ExtensionDataObject properties preventing you from easily serializing your model classes to JSON and you don't want to make shadow classes (::gasp:: yes I know the .NET Fx loves ceremony, I however do not) then you can use a custom JavaScriptConverter to ignore those properties. When you have control of a class you can put a NonSerialized attribute on properties but that becomes substantially more difficult when a tool is responsible for generating the class file and cheerfully overwrites any changes you may make if you even open the file to glance at its contents. Yes shitty *.dbml tool in Visual Studio, I'm looking at you.

So let's say you have this simple helper class:

// JsonSerializationUtility.cs
public static class JsonSerializationUtility
{
	public static string ToJson(this object obj, string wrapper = null)
	{
		var json = new JavaScriptSerializer().Serialize(obj);
		if (!string.IsNullOrEmpty(wrapper))
			json = "{ \"" + wrapper + "\": " + json + " }";

		return json;
	}

	public static T Deserialize<T>(string json)
	{
		var jss = new JavaScriptSerializer();
		jss.RegisterConverters(new [] { new ExtensionDataObjectConverter() });
		var result = jss.Deserialize<T>(json);
		return result;
	}
}

... then you'll need this handy ExtensionDataObjectConverter class!

// ExtensionDataObjectConverter.cs
public class ExtensionDataObjectConverter : JavaScriptConverter
{
	public override IEnumerable<Type> SupportedTypes
	{
		get
		{
			return new ReadOnlyCollection<Type>(new [] { typeof(ExtensionDataObject) });
		}
	}

	public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
	{
		return null;
	}

	public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
	{
		return null;
	}
}