[Mono-dev] Replicating System.Web.Script.Serialization bugs

R. Tyler Ballance tyler at monkeypox.org
Sun Sep 23 09:57:44 EDT 2007


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




-------------- next part --------------
A non-text attachment was scrubbed...
Name: JsonTest.cs
Type: application/octet-stream
Size: 731 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20070923/2ffec387/attachment.obj 
-------------- next part --------------

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]




-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 186 bytes
Desc: This is a digitally signed message part
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20070923/2ffec387/attachment.bin 


More information about the Mono-devel-list mailing list