Home Dashboard Directory Help
Search

DataContractJsonSerializer should serialize Dictionary<K,V> as a JSON associative array. by cheeso


Status: 

Resolved
 as By Design Help for as By Design


7
4
Sign in
to vote
Type: Bug
ID: 558686
Opened: 5/12/2010 11:11:08 AM
Access Restriction: Public
0
Workaround(s)
view
3
User(s) can reproduce this bug

Description

The DataContractJsonSerializer is not interoperable with the definitive javascript library for json serialization, which is available at http://www.JSON.org/json2.js .

#1 - consider the case of serializing in Javascript, and de-serializing in .NET:

Using that library from within Javascript, it is easy to produce json. This is the javascript code:

    var a = {};
    a["Red"] = "Rosso";
    a["Blue"] = "Blu";
    a["Green"] = "Verde";

    // use utility class from http://www.JSON.org/json2.js
    var json = JSON.stringify(a);
    // json = {"Red":"Rosso","Blue":"Blu","Green":"Verde"}

But, this json string cannot be de-serialized by DCJS into a Dictionary. Trying to de-serialize this string using DCJS produces a null object.

#2 - consider the case where a .NET Dictionary is serialized into JSON using DCJS, then
de-serialized via the javascript library.

This is the C# code:

    [CollectionDataContract]
    public class Clazz : Dictionary<String,String> {}

                var c1 = new Clazz();
                c1["Red"] = "Rosso";
                c1["Blue"] = "Blu";
                c1["Green"] = "Verde";

Serializing c1 produces this JSON:

[{"Key":"Red","Value":"Rosso"},{"Key":"Blue","Value":"Blu"},{"Key":"Green","Value":"Verde"}]

De-serializing this in Javascript via JSON2.js produces an array of objects, not a dictionary.


Serialization between DataContractJsonSerializer and JSON2.js ought to be reflexive. It should be possible to round-trip between these serializers, in either direction.


Details
Sign in to post a comment.
Posted by Nektar on 2/8/2014 at 3:57 PM
Isn't this usecase what the UseSimpleDictionaryFormat property is trying to address?http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.usesimpledictionaryformat(v=vs.110).aspx
The property's documentation gives no explaination on what it does. It's really vague, just repeating the name of the property without adding any information.
However, I have read on Stackoverflow that this property, when used for this purpose, does not actually work. http://stackoverflow.com/questions/13631208/deserializing-a-json-object-hierarchy-into-a-hierarchy-of-dictionarystring-obj
So, please improve the docs for this property and fix any bugs associated with it, if any.
Deal with this confusion, please.
Posted by Isaiyavan Babu Karan on 6/7/2012 at 10:49 PM
What if my data looks like

{
    "vid": 3855,
    "properties": {
        "email": {
            "value": "fakeboy1984@gmail.com",
            "versions": [
                {
                    "value": "fakeboy1984@gmail.com",
                    "source-type": "API",
                    "source-id": null,
                    "source-label": null,
                    "timestamp": 1339076619285,
                    "selected": false
                }
            ]
        },
        "createdate": {
            "value": "1339076619285",
            "versions": [
                {
                    "value": "1339076619285",
                    "source-type": "API",
                    "source-id": null,
                    "source-label": null,
                    "timestamp": 1339076619285,
                    "selected": false
                }
            ]
        }
    }
}

so i need Dictionary<string,ComplexObject> , "Posted by Microsoft on 5/20/2010 at 6:40 PM " by ramesh do not show mercy on us!

I hope something will come soon.
Posted by Lassor on 12/19/2011 at 5:54 PM
It should be able to do this out-of-the-box without dancing with custom serialization
Posted by Microsoft on 5/28/2010 at 11:52 AM
Cheeso,
Thanks for posting this. The behavior of the DataContractJsonSerializer when serializing a Dictionary<TKey,TValue> is designed to accommodate a variety of types as keys - not just strings. As such it generates an array of key value objects given that in some cases, the key's themselves are objects. So right now, this behavior is by design. That said - we've heard this request from a few different customers and we are definitely considering adding this capability in a future release. One workaround that you can try now depending on your scenario would be to apply [Serializable] to Clazz, implement ISerializable, and remove Dictionary<string,string> as the base class (you could make it a private member and expose whichever methods you want to on Clazz). This would give you control over the serialization of the dictionary, but you loose the Dictionary<string, string> type.

HTH,
Ed
Posted by vcomrhencke on 5/21/2010 at 8:07 AM
@cheeso, in your XML example in the comment for potential output from a hypothetical "UseKeysAsElementNames" property, you use the Key value as the element name. However, XML disallows element names that begin with numbers, spaces or punctuation.
Posted by cheeso on 5/21/2010 at 8:01 AM
@_akidan, Regarding keynames that begin with numbers, spaces or punctuation - I'm not sure what you mean. What's the problem?
Posted by cheeso on 5/21/2010 at 7:59 AM
Ramesh, can you boil down the workaround ? the post you mentioned includes coverage of 3 distinct serializers, along with lots of editorial comment about which to use when. There's a whole bunch of code, and I'm not sure what applies to this specific situation.

I'm interested in the DataContractJsonSerializer, specifically. Is there a way, today, to customize the way DCJS serializes dictionaries? If so... what is it, succintly.

Is there a HOWTO KB Article? Or can you post a succint workaround here, on the Workarounds tab?
thanks.
Posted by Microsoft on 5/20/2010 at 6:40 PM
thank you for reporting this suggestion. We will consider this for our next release. The post has a workaround if you are blocked on this issue -
http://my6solutions.com/post/2009/06/30/DataContractSerializer-DataContractJsonSerializer-JavaScriptSerializer-XmlSerializer-for-serialization.aspx

thanks,
     Ramesh
Posted by vcomrhencke on 5/13/2010 at 9:12 AM
cheeso, how would UseKeysAsElementNames work for serializing key names that begin with numbers, spaces or punctuation?
Posted by cheeso on 5/13/2010 at 5:37 AM
Maybe the correct solution is to provide an additional property on CollectionDataContract that indicates whether to map key names to element names, or to map key names into element values. Right now there are properties like KeyName and ValueName, that ostensibly set the element names for the key+value in the serialized format of the dictionary.

Imagine a separate boolean property on CollectionDataContract that says "UseKeysAsElementNames", which when true would override the KeyName+ValueName properties. This would allow the correct JSON to be produced. It would also work with the XML serializer (DataContractSerializer) in a similar way. Rather than geting

<root>
     <items>
         <item>
         <KeyName>Red</KeyName>
         <ValueName>Rosso</ValueName>
         </item>
         <item>
         <KeyName>Blue</KeyName>
         <ValueName>Blu</ValueName>
         </item>
         ...
     </items>
    </root>

... setting this property to true could generate this for a dictionary:

<root>
     <items>
         <Red>Rosso</Red>
         <Blue>Blu</Blue>
            ...
     </items>
    </root>
Posted by Microsoft on 5/13/2010 at 3:04 AM
Thanks for your feedback. We were able to reproduce the issue you are seeing. We are routing this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by Microsoft on 5/12/2010 at 5:05 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Posted by cheeso on 5/12/2010 at 11:13 AM
See also, a prior rant from someone else on this topic:
http://blog.dotsmart.net/2008/01/07/wcf-json-serialization-is-flawed/
Sign in to post a workaround.