AjaiJA
AjaiJA

Reputation: 67

Deserializing the JSON object passed from Ajax to ASP.NET MVC

I'm trying to send the JSON object through Ajax request to ASP.NET MVC. While getting the JSON object in the backend, it receives the object in string format as shown below.

How to deserialize it into a C# object?

C# ASP.NET MVC code:

public string GetLists(string list1)
{
    return JsonConvert.SerializeObject(list1, JsonSetting);
}

JavaScript code:

button.onclick=()=> {
    let xhr = new XMLHttpRequest()     
    xhr.onreadystatechange = () => {
        if (xhr.readyState == 4 && xhr.status == 200) {
            console.log(xhr.response)
        }
    }
    let list1=[
        {"id":"1a","level":1},
        {"id":"2b","level":14},
        {"id":"3c","level":23}
    ]
    var params ="list1=" + JSON.stringify(list1)
    xhr.open("POST", "/Status/GetLists");
    xhr.setRequestHeader('content-type', "application/x-www-form-urlencoded");
    xhr.send(params);
}

Output:

[
    {\"id\":\"1a\",\"level\":1},
    {\"id\":\"2b\",\"level\":14},
    {\"id\":\"3c\",\"level\":23}
]

Upvotes: 0

Views: 1376

Answers (3)

tlucian
tlucian

Reputation: 186

You are trying to send a json object with a wrong content-type, in your case the content-type should be application/json and you don't have to add "params" + JSON.stringify(list1) as this will be sent in the request body, you should send just the list1 variable.

xhr.setRequestHeader('content-type', "application/json");
xhr.send(JSON.stringify(list1));

Then you will be able to deserialize the object in your backend endpoint like:

    public class Item
    {
        public string id { get; set; }
        public string level { get; set; }
    }

    [HttpPost]
    public List<Item> GetLists([FromBody] object value)
    {
        var items = JsonConvert.DeserializeObject<List<Item>>(value.ToString());

        return items;
    }

Upvotes: 0

Serge
Serge

Reputation: 43860

your data is serialized twice, at first you serialize it manually , after this net serialized it automaticaly to send data back. So you don't need to serialize it at all, net will do it for you. Change your action to this

public ActionResult<List<Item>> GetLists([FromBody] List<item> list)
{
    return Ok(list);
}

class

 public class Item
    {
        public string id { get; set; }
        public string level { get; set; }
    }

and ajax

    var params =JSON.stringify(list1);
    xhr.open("POST", "/Status/GetLists");
    xhr.setRequestHeader('content-type', "application/json");
    xhr.send(params);

Upvotes: 1

Maik
Maik

Reputation: 46

You can use System.Text.Json.JsonSerializer but you should include a type for deserialization so that c# knows the kind of data you are trying to receive.

In your code, you only give back the string but not a c# object so you have to specify a class or an interface to model your data.

Example snippet for receiving the data:

using System;
using System.Collections.Generic;
using System.Text.Json;

// define the structure of the object you want to recieve

interface MyDataStructure
{
    public string id { get; set; }
    public int level { get; set; }

}
class Program
{
    public void ReadData(string jsonData)
    {
        // Creating a list of objects from your type. The Json Serializer is flexible and also workes when using Arrays

        List<MyDataStructure> data = JsonSerializer.Deserialize<List<MyDataStructure>>(jsonData);
        foreach (var obj in data){
            Console.WriteLine($"{obj.id}||{obj.level}");
        }
    }
}

I recommend you should check out the docs on deserialization and serialization.

An alternative to the .Net JsonSerializer is Newtonsofts Json.NET

Upvotes: 3

Related Questions