Serializing Objects as JSON using Atlas, JSON.NET and AjaxPro [Part 2]
As there was a little discussion about serialization of .NET types and deserialization of these genereted JSON strings I have updated Ajax.NET Professional (version 6.7.9.1) to allow parsing of new Date statements, too. You can use the JSON generated string to do a deserialization right after, now.
I tried to write some other tests to see how these three frameworks compare when running serialize() and deserialze() methods. JSON.NET was not able to serialize a simple DateTime instance. When using a DateTime as property in a class it could be serialized, but deserializing didn't work because of the wrong date format (which is different here in Germany and a lot of other countries). Atlas is working similar to the AjaxPro serialization, but not using UTC.
I started to add more properties/fields to the Person class example to see which .NET data types are really working?
[AjaxPro.AjaxNoTypeUsage]
public class Person
{
public MyColor color = MyColor.Yellow;
public MyColor2 color2 = MyColor2.Red; // not working with Atlas
public DateTime dt = DateTime.Now;
public float f = 2.3F;
public double d = 1.1;
public int i = 999;
public int[] I = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
public bool b = false;
public char c = '@';
public List<string> s = new List<string>();
public decimal dec = 0.1M;
public string S = "\r\n\t\f\b?{\\r\\n\"\'";
public Person()
{
s.Add("Hello World");
s.Add("öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~");
s.Add(" ");
}
}
public enum MyColor
{
Black, Red, Yellow, White
}
public enum MyColor2 : byte
{
Black, Red, Yellow, White
}
The class above is only working with AjaxPro. JSON.NET and Atlas have both problems with non-US formats like dates or the decimal seperator. Compare following JSON outputs:
Ajax.NET Professional:
{"color":2,"color2":1,"dt":new Date(Date.UTC(2006,6,9,12,18,22,704)),
"f":2.3,"d":1.1,"i":999,"I":[1,2,3,4,5,6,7,8,9],"b":false,"c":"@",
"s":["Hello World","öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"," "],
"dec":0.1,"S":"\r\n\t\f\b?{\\r\\n\"'"}
JSON.NET:
{"color":2,"color2":1,"dt":"07/09/2006 14:18:22",
"f":2.3,"d":1.1,"i":999,"I":[1,2,3,4,5,6,7,8,9],"b":false,"c":64,
"s":["Hello World","öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"," "],
"dec":"0.1","S":"\r\n\?{\\r\\n\"'"}
Atlas:
{"color":2, MISSING color2!! "dt":new Date(1152454818040),
"f":2.3,"d":1.1,"i":999,"I":[1,2,3,4,5,6,7,8,9],"b":false,"c":"@",
"s":["Hello World","öäüÖÄÜ\\\'{new Date(12345);}[222]_µ@²³~"," "],
"dec":0.1,"S":"\r\n\?{\\\r\\n\"\'"}
If you have a deep look in the JSON output you will see a lot of different serializations. There are some that are ok if the deserialization is only used for .NET, but using the JSON output in JavaScript it will very bad if you do not get a real Date object or if a character is represented as the ASCII code (see JSON.NET that will serialize the @ sign to 64): The color2 property is using a byte enum which is not supported by Atlas, I simple removed this for the test above.
Next, I tried to use the JSON output to create a new instance of the Person class. Hm, again only Ajax.NET Professional is working correct. Atlas cannot convert any value with a decimal seperator if it is using non-US culture info.
2 Comments
Comments have been disabled for this content.
Atif Aziz said
This is all fine, but it's not really JSON anymore. Call it may be JSON-on-a-date. :) What you're doing here is essentially an extension to JSON the moment you've introduced the "new" operator and even if only for a very specific case. The main problem is that your JSON can no longer be parsed by most other JSON libraries that are conforming to the standard, including JSON.NET and Jayrock-JSON. Atlas is also making the same violation of the data format. It's fine if you know where your JSON is going to end up, like in JavaScript or back in your own library. If not, dates continues to be a sore problem and the only way to solve it iwithin the constraints of JSON is to use a number or a string (the latter being more human-readable). Then, each end of the wire has to say, somehow, that I would like that number or string to be interpreted as a date. This is just not going to be as automatic as we would all like to be. I think there's no harm in making extensions as long as the user has the option to turn them off to get the unadultered version of the data format.
interactive said
Atif, yes, you are right. I have already changed the internal and stand-alone JSON parser to do not use the "new" statement. It will be used only if Ajax.NET Professional will return data to a web browser (JavaScript). My JSON parser will allow to parse all types, I tried this with your JSON output and the output from others.