Pytanie Dlaczego Json.Encode nie koduje poprawnie danych zwróconych przez Json.Decode?


Gdy używam klasy Json z System.Web.Helpers i uruchamiam poniższy kod, spodziewałem się, że stworzy on ciąg json zawierający te same informacje co oryginalny ciąg, ale dziwnie to tylko zwraca ciąg znaków { "employees" : {} } i całkowicie pomija tablicę i zastępuje ją pustym obiektem?

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" : {} }

Kiedy patrzę na obiekt zwrócony z Json.Decode, tablica jest dekodowana do DynamicJsonArray. Jeśli utworzę obiekt .NET z tablicami / listami / słownikami, wydaje się, że są one idealnie zakodowane, więc problem wydaje się być związany z DynamicJsonArray.

Jeśli koduję / dekoduję złożony ciąg jsonów bez tablic, wygląda na to, że działa poprawnie:

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"
          }
     }
}
*/

Przyjrzałem się dokumentacji na msdn, ale nie mogłem znaleźć żadnych powodów, dla których to nie powinno działać. Czy może to być błąd, czy jest to zgodne z projektem?

Aktualizacja

Jeśli mam ciąg jsonów, który jest tablicą w węźle głównym, to poprawnie koduje / dekoduje, więc naprawdę zaczynam podejrzewać, że jest to błąd (lub przynajmniej bardzo niespójny):

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"
    }
]
*/

Zaktualizuj 2

Zdecydowałem się jednak otworzyć problem z Microsoftem. Zobaczmy, co mają do powiedzenia: http://connect.microsoft.com/VisualStudio/feedback/details/779119/data-from-json-decode-is-not-encoded-correctly-when-encoding-with-json-encode


12
2018-02-13 09:23


pochodzenie


Nie jestem ekspertem w tej bibliotece, ale wszystko wygląda na czyste, więc głosowałbym, że to błąd. Ale obsługa tablic jest tak podstawową funkcjonalnością w JSON, że nie mogę uwierzyć, że tego nie zauważą .. - quetzalcoatl


Odpowiedzi:


Też mam ten błąd, na szczęście biblioteka jest teraz open source, więc możemy sami naprawić błąd: https://aspnetwebstack.codeplex.com/SourceControl/latest

Poprawka znajduje się w 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;
}

Zgłaszałem błąd z sugerowaną poprawką na stronie codeplex: https://aspnetwebstack.codeplex.com/workitem/1085


6
2018-06-08 05:59





Myślę, że powinieneś używać Json.NET zamiast tego. Widzieć: Json.NET na Codeplex


0
2018-02-14 16:22



To nie odpowiada na to pytanie, chodzi o konkretny problem w konkretnej bibliotece, a nie o najlepszy sposób kodowania jsona. - CodesInChaos


Czy zastanawiałeś się nad tworzeniem i używaniem klas, które możesz następnie serializować / deserializować?

JavaScriptSerializer serializer = new JavaScriptSerializer();
// to JSON
string json = serializer.Serialize(EmployeeList);
// from JSON
EmployeeList employeeList = serializer.Deserialize<EmployeeList>(json);

Niemal zawsze serializuję / deserializuję, ponieważ potrzebuję danych jako obiektu do użycia podczas wykonywania. Ale myślę, że to zależy od twojej sprawy.


0
2018-02-20 17:14