Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly deserialize a JSON string into the class that contains a nested List of another class

I have the following object graph and I'm using Jquery's $.Ajax() to send this identical "View" object in JSON (stringified) from the browser to a Page Method on ASP.Net. The JAvascript deserialization works for all of the strings and int's in the View class but My List<DataItem> is empty.

What I tried: Using chrome dev tools, I took the stringified JSON, created a unit test and used both the DataContractJsonSerializer and the JavaScriptSerializer. The DataContractJsonSerializer object deserialized my object graph correctly but the JavaScriptSerializer dumped my List. How can I get the correct deserialization on my page method ?

public class View
{
    public string Text { get; set; }
    public string AnotherText { get; set; }
    public Int SomeInt { get; set; }
    public List<DataItem> { get; set; }
}

public class DataItem
{
    public Person person {get;set}
}

public class Person
{
    public int Age {get;set}
}

   var dataa = {mqvm: mqvmJSON };
    $.ajax({
        type: "POST",
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify( dataa ),
        url: "GoHere.aspx/WebMethodName",
        success: function(data) {
            alert(data.d);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            alert(jqXHR.responseText + ' ' + errorThrown);
        }
    });

Instead of this (the view obj as a param).

    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    [WebMethod]
    public static string CreateResponseReview(View mqvm)
    { 
        return "Success";
    }

how can I get this? (the string param)

    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    [WebMethod]
    public static string CreateResponseReview(string mqvm)
    { 
        //do manual JSON deserialization here.

        return "Success";
    }

My JSON looks like this.

    {
    "Text": "6",
    "AnotherText":"wow"
    "SomeInt": 5,
    "DataItem":[
        {
            "person":{
                "Age":23
            }
        },
        {
            "person":{
                "Age":42
            }
        }
    ]
}
like image 892
EbbnFlow Avatar asked Sep 26 '11 18:09

EbbnFlow


People also ask

How do I deserialize a JSON file?

A common way to deserialize JSON is to first create a class with properties and fields that represent one or more of the JSON properties. Then, to deserialize from a string or a file, call the JsonSerializer. Deserialize method.

How do you deserialize a JSON string in Python?

To deserialize the string to a class object, you need to write a custom method to construct the object. You can add a static method to ImageLabelCollection inside of which you construct Label objects from the loaded JSON dictionary and then assign them as a list to the class variable bbox.

What is deserialize in JSON?

JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object).


2 Answers

I figured it out.

I didn't want to use the JavascriptSerializer class because it dumped my nested list so I forced it to pass me the object as a string and then I manually deserialized it. I also kept getting "no parameterless constructor defined for type of u0027system.string u0027"

Remember that U0027 is an apostrophe so the runtime might be thinking that there is an actual type named "System.string" and not System.string. My problem was - I wasn't correctly delimiting the parameters in the item below called data2. I had to put \' ticks \' around the key and the value.

function requestHtmlFromServer(mqvmJSON) {
    var mqvmstring = JSON.stringify(mqvmJSON);
    var data2 = "{\'mqvm\':\'" + mqvmstring + "\' }"; \\<--the problem
    $.ajax({
        type: "POST",
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        data: data2,
        url: "MedicalInformation.aspx/CreateResponseReview",
        success: function(data) {
            alert(data.d);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            alert(jqXHR.responseText + ' ' + errorThrown);
        }
    });
}


    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    [WebMethod]
    public static string CreateResponseReview(string mqvm)
    {
        string noNewLines = mqvm.Replace("\n", "");
        View viewModel = ToObjectFromJSON<View>(noNewLines);
        //do my other stuff here

        return "Success";
    }
    public static T ToObjectFromJSON<T>(string jsonString)
    {
        var serializer = new DataContractJsonSerializer(typeof(T));
        var memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(jsonString));
        var newObject = (T)serializer.ReadObject(memoryStream);
        memoryStream.Close();
        return newObject;
    }
like image 94
EbbnFlow Avatar answered Sep 28 '22 15:09

EbbnFlow


Try using the following:

Deserialisation Code

string json = "{\"text\":\"some text\",\"anotherText\":\"some more text\", \"someInt\":1, \"dataItems\":[{\"person\":{age:25}},{\"person\":{age:20}}]}";

JavaScriptSerializer serializer = new JavaScriptSerializer();
View view = serializer.Deserialize<View>(json);

Classes

public class View
{
    public string Text { get; set; }
    public string AnotherText { get; set; }
    public int SomeInt { get; set; }
    public List<DataItem> DataItems { get; set; }
}

public class DataItem
{
    public Person person { get; set; }
}

public class Person
{
    public int Age {get;set;}
}

JSON

{
    "text":"some text",
    "anotherText":"some more text", 
    "someInt":1, 
    "dataItems":
        [
            {"person":{age:25}},
            {"person":{age:20}}
        ]
}
like image 41
jdavies Avatar answered Sep 28 '22 13:09

jdavies