Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Json.Encode encode data returned from Json.Decode correctly?

Tags:

json

c#

.net

When using the Json class from System.Web.Helpers and I run the following code, I expected it to produce a json string containing the same information as the original string, but strangely it only returns the string { "employees" : {} } and omits the array entirely and replaces it with an empty object?

string jsonData = "{ \"employees\": [ { \"firstName\":\"John\" , \"lastName\":\"Doe\" }, { \"firstName\":\"Anna\" , \"lastName\":\"Smith\" }, { \"firstName\":\"Peter\" , \"lastName\":\"Jones\" } ] }";
var json = Json.Decode(jsonData);
string result = Json.Encode(json); 
// result is: { "employees" : {} }

When I look at the object returned from Json.Decode the array is decoded into a DynamicJsonArray. If I create a .NET object with arrays/lists/dictionaries it seems to encode them perfectly so the problem seems to be related to DynamicJsonArray.

If I encode/decode a complex json string without arrays it seems to be working fine:

string jsonData = "{ \"firstName\": \"John\", \"lastName\": \"Doe\", \"family\": { \"mother\": { \"firstName\": \"Anna\", \"lastName\": \"Smith\" }, \"father\": { \"firstName\": \"Peter\", \"lastName\": \"Jones\" }  }  }";
var json = Json.Decode(jsonData);
string result = Json.Encode(json); 
/* result is (formatted for readability):
{
    "firstName" : "John",
    "lastName" : "Doe",
    "family" : {
        "mother" : {
            "firstName" : "Anna",
            "lastName":"Smith"
         },
         "father" : {
             "firstName" : "Peter",
             "lastName" : "Jones"
          }
     }
}
*/

I have looked at the documentation on msdn but couldn't find any reasons why this shouldn't work. Could it be a bug or is it by design?

Update

If I have a json string that's an array at the root node, it encodes/decodes correctly so I really start to suspect that this is a bug (or at least it's very inconsistent):

string jsonData = "[ { \"firstName\":\"John\" , \"lastName\":\"Doe\" }, { \"firstName\":\"Anna\" , \"lastName\":\"Smith\" }, { \"firstName\":\"Peter\" , \"lastName\":\"Jones\" } ]";
var json = Json.Decode(jsonData);
string result = Json.Encode(json);
/* result is (formatted for readability):
[
    { 
        "firstName" : "John",
        "lastName" : "Doe"
    },
    {
        "firstName" : "Anna",
        "lastName" : "Smith" 
    },
    {
        "firstName" : "Peter",
        "lastName" : "Jones"
    }
]
*/

Update 2

I decided to open an issue with Microsoft after all. Let's see what they have to say: http://connect.microsoft.com/VisualStudio/feedback/details/779119/data-from-json-decode-is-not-encoded-correctly-when-encoding-with-json-encode

like image 807
Per Avatar asked Feb 13 '13 09:02

Per


People also ask

What is JSON encode and JSON decode?

Encoding is used to bundle data with respect to a particular format. This process will be required to preserve data consistency. Decoding is a reverse process that reverts encoded data back to its original form.

What does json_decode return?

The json_decode() function can return a value encoded in JSON in appropriate PHP type. The values true, false, and null is returned as TRUE, FALSE, and NULL respectively. The NULL is returned if JSON can't be decoded or if the encoded data is deeper than the recursion limit.

Which of the following function is used to encode the data into JSON format?

The json_encode() function is used to encode a value to JSON format.

What does json_encode return?

The json_encode() function can return a string containing the JSON representation of supplied value. The encoding is affected by supplied options, and additionally, the encoding of float values depends on the value of serialize_precision.


1 Answers

I'm experiencing this bug too, luckily the library is now open source so we can fix the bug ourselves: https://aspnetwebstack.codeplex.com/SourceControl/latest

The fix is in System.Web.Helpers/DynamicJavaScriptConverter.cs

// Get the value for each member in the dynamic object
foreach (string memberName in memberNames)
{
    //replace this line
    //values[memberName] = DynamicHelper.GetMemberValue(obj, memberName);

    //with this code
    var value = DynamicHelper.GetMemberValue(obj, memberName);
    if (value is DynamicJsonArray)
        value = (object[])(DynamicJsonArray)value;
    values[memberName] = value;
}

I've filed a bug with the suggested fix on the codeplex site: https://aspnetwebstack.codeplex.com/workitem/1085

like image 174
Michael Avatar answered Oct 12 '22 10:10

Michael