I was playing around with Json.NET while trying to move some data back and forth between .NET and Flex. I found that I needed to deserialize a string that looks something like:
string json = @"{param1:{FirstName:'Jay',Age:2},param2:{FirstName:'Ray',Age:3}}";
where param1 and param2 are parameters to a method that I want to invoke as a remote service. I have two objects that I want to deserialize within a container object (the outer { }). I really don’t care about the container object but I have no way to tell Json.NET to ignore it. I have to have a real concrete to deserialize the container. I didn’t want to create specific objects for each call being made (there could be a lot) so I created a simple generic object that looks something like the following (error handling removed for clarity):
public class ParameterCollection
{
private readonly Dictionary<string, object> parameters;
internal ParameterCollection(Dictionary<string, object> parameters)
{
this.parameters = parameters;
}
public object this[string name]
{
get { return parameters[name]; }
}
public int Count
{
get { return parameters.Count; }
}
}
In order to deserialize to a ParameterCollection object, I needed to create a converter class that inherits from JsonConverter. It ended up looking like the following (error handling removed for clarity):
public class ParameterCollectionJsonConverter : JsonConverter
{
private readonly Type[] parameterTypes;
private readonly Dictionary<string, object> parameterInstances;
public ParameterCollectionJsonConverter(params Type[] parameterTypes)
{
this.parameterTypes = parameterTypes;
this.parameterInstances = new Dictionary<string, object>(parameterTypes.Length);
}
public override bool CanConvert(Type objectType)
{
return objectType.IsAssignableFrom(typeof(ParameterCollection));
}
public override object ReadJson(JsonReader reader, Type objectType)
{
reader.Read(); // read past start object token
for (int i = 0; i < parameterTypes.Length; i++)
{
string parameterName = reader.Value as string;
this.parameterInstances.Add(parameterName, new JsonSerializer().Deserialize(reader, parameterTypes[i]));
reader.Read();// read past end object token
}
reader.Read();// read past end object token
return new ParameterCollection(parameterInstances);
}
public static ParameterCollection Deserialize(TextReader jsonTextReader, params Type[] types)
{
JsonSerializer serializer = new JsonSerializer();
serializer.Converters.Add(new ParameterCollectionJsonConverter(types));
JsonReader reader = new JsonReader(jsonTextReader);
return serializer.Deserialize(reader, typeof(ParameterCollection)) as ParameterCollection;
}
}
So now I can deserialize to a ParameterCollection by passing in the types of each parameter like so:
TextReader tr = new StringReader(@"{param1:{FirstName:'Jay',Age:2},param2:{FirstName:'Ray',Age:3}}");
ParameterCollection paramCollection = ParameterCollectionJsonConverter.Deserialize(tr, typeof(SomeObject), typeof(SomeObject));
SomeObject someObj1 = paramCollection["param1"] as SomeObject;
I’m sure as soon as I post this somebody will let me know of a built-in way to do the same thing.
Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Hi Ray,
The .NET framework has two separate classes for serializing/deserializing Javascript objects. Have you tried either of those?
System.Web.Script.Serialization.JavaScriptSerializer
http://msdn2.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx
It’s marked as “obsolete”, but I’ve heard rumors that it isn’t going anywhere in the framework.
System.Runtime.Serialization.Json.DataContractJsonSerializer
http://msdn2.microsoft.com/en-us/library/system.runtime.serialization.json.aspx
DataContractJsonSerializer is part of the Indigo/WCF namespace.
@Scott – thanks for the heads up! I’ll try the DataContractJsonSerializer in the future. Right now, our project is still in 2.0, but we will be moving to 3.5 soon. I was using the serializer in ASP.NET AJAX for 2.0 with web services, but I needed a different way to handle errors because Flex wasn’t playing nice. Since I’m not using ASP.NET web services anymore, I thought I’d try a lib that just had what I need in it.
@Ray:
Try those first. If you don’t have luck, I wrote a quick and dirty test using JScript.NET (Yes, trust me, it rocks — just a few lines to do JSON [de]serialization) and it was at least twice as fast as that code you posted.
@Chad – really? Can you post some code? Does it run in 2.0?
@Ray: Yes, JScript.NET doesn’t appear to have been touched in .NET 3.5 (since 3.5 is mostly C#/VB compiler extensions + libs, no CLR/CLI changes).
I’m workin’ on getting the code packaged up
@Chad: I’d like to see that JScript.NET code for doing JSON [de]serialization. When (if) you get some time away from your new job can you post it?
Thank you for sharing such a good thing.
I am also playing JSON.NET1.3 for ajax grid data feed, but I can’t get it work. Are you using JSON.NET2.0?
@Jim – No, I haven’t tried JSON.NET 2.0 yet.