I discovered that whilst consuming Facebook's API data in JSON format, that both .NET 2.0 and Mono (from trunk) have the exact same System.Web.Script.Serialization bug when dealing with empty value fields in the JSON key/value string, for example:

{"some_key" : ""}

Which is handled properly as an empty value by Python and Javascript alike, barfs inside the stronger-typed C#, when you try to serialize it to a "long" value (for example), throwing the following exception on both .NET and Mono

Unhandled Exception: System.Exception: is not a valid value for Int64. ---> System.FormatException: Input string was not in the correct format: s.Length==0. at System.Int64.Parse (System.String s, NumberStyles style, IFormatProvider fp) [0x00000] at System.ComponentModel.Int64Converter.ConvertFromString (System.String value, System.Globalization.NumberFormatInfo format) [0x00000] at System.ComponentModel.BaseNumberConverter.ConvertFrom (ITypeDescriptorContext context, System.Globalization.CultureInfo culture, System.Object value) [0x00000]

[full stack trace from attached test code at the bottom of this email]


Ideally this would just *not* be serialized out, leaving the object's property that maps to "some_key" empty/uninitialized, but instead the application that consumes and deserializes the JSON will explode, especially if the JSON provider (Facebook in my case) provides fields such as this as optional.

As I mentioned to sontek in the IRC channel, it certainly seems like I'm screwed in this case, since we are "compatible" with Microsoft's bugs :( So the bigger question is, what work around or recourse do I have in this case? I have kicked around the idea of adding a Mono.Script.Serialization to trunk that would essentially just apply a series of patches to System.Web.Script.Serialization, but I'd rather avoid that route as it doesn't tend to grow well, but I don't see a really decent workaround except to implement a "magic" property for EVERY single optional JSON key (which in some calls can be up to about 50 keys) to do a Convert.ToInt64 if there's a string on get {}, otherwise return a null (this sucks, and I don't want to implement it for every frakking deserializable attribute that could need to be deserialized as anything but a string)

I've attached my test case, but I have a sense someone is going to point out that the emperor has no clothes, and that I am indeed screwed :-P


Cheers




Attachment: JsonTest.cs
Description: Binary data


Unhandled Exception: System.Exception: is not a valid value for Int64. ---> System.FormatException: Input string was not in the correct format: s.Length==0. at System.Int64.Parse (System.String s, NumberStyles style, IFormatProvider fp) [0x00000] at System.ComponentModel.Int64Converter.ConvertFromString (System.String value, System.Globalization.NumberFormatInfo format) [0x00000] at System.ComponentModel.BaseNumberConverter.ConvertFrom (ITypeDescriptorContext context, System.Globalization.CultureInfo culture, System.Object value) [0x00000]

  --- End of inner exception stack trace ---

at System.ComponentModel.BaseNumberConverter.ConvertFrom (ITypeDescriptorContext context, System.Globalization.CultureInfo culture, System.Object value) [0x00000] at System.ComponentModel.TypeConverter.ConvertFromString (ITypeDescriptorContext context, System.Globalization.CultureInfo culture, System.String text) [0x00000] at System.ComponentModel.TypeConverter.ConvertFromInvariantString (ITypeDescriptorContext context, System.String text) [0x00000] at System.ComponentModel.TypeConverter.ConvertFromInvariantString (System.String text) [0x00000] at System.Web.Script.Serialization.JavaScriptSerializer.ConvertToType (System.Type type, System.Object obj) [0x00000] at System.Web.Script.Serialization.JavaScriptSerializer.ConvertToObject (IDictionary`2 dict, System.Type type) [0x00000] at System.Web.Script.Serialization.JavaScriptSerializer.ConvertToType (System.Type type, System.Object obj) [0x00000] at System.Web.Script.Serialization.JavaScriptSerializer.ConvertToType [JsonObject] (System.Object obj) [0x00000] at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize [JsonObject] (System.String input) [0x00000]
  at JsonTests.JsonTest.Main (System.String[] args) [0x00000]




Attachment: PGP.sig
Description: This is a digitally signed message part

_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to