Search code examples
c#json.net

Can't convert JSON to C# class


I have some troubles convertin JSON response to a C# class.

I'm getting the following JSON respone into a string object:

"[{\"slaveId\":31,\"funcCode\":3,\"address\":86,\"quantity\":2,\"data\":[4,30,241,73,0]}]"

I validated the format on this web site , the string is a valid JSON format.

I converted the above response to a C# class using json2csharp and got the following code:

// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); 
public class MyArray
{
    public int slaveId { get; set; }
    public int funcCode { get; set; }
    public int address { get; set; }
    public int quantity { get; set; }
    public List<int> data { get; set; }
}

public class Root
{
    public List<MyArray> MyArray { get; set; }
}

I added the above code to my project, the final result is:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;

namespace ModbusJsonTest
{
    class Program
    {
        static void Main(string[] args)
        {
        const int PORT_NO = 30001;
        const string SERVER_IP = "192.168.1.1";

        //---data to send to the server---

        StringBuilder request = new();
        request.Append("{");
        request.Append("\"funcCode\":3,");
        request.Append("\"slaveId\":31,");
        request.Append("\"address\":86,");
        request.Append("\"quantity\":2,");
        request.Append("\"interval\":0");
        request.Append("}");


        //---create a TCPClient object at the IP and port no.---
        TcpClient client = new TcpClient(SERVER_IP, PORT_NO);
        NetworkStream nwStream = client.GetStream();
        byte[] bytesToSend = ASCIIEncoding.ASCII.GetBytes(request.ToString());

        //---send the text---
        Console.WriteLine("Sending : " + request.ToString() + "/n");
        nwStream.Write(bytesToSend, 0, bytesToSend.Length);

        //---read back the text---
        byte[] bytesToRead = new byte[client.ReceiveBufferSize];
        int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);
        string myJsonResponse = Encoding.ASCII.GetString(bytesToRead, 0, bytesRead);
        Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);

        client.Close();
    }


}

// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); 
public class MyArray
{
    public int slaveId { get; set; }
    public int funcCode { get; set; }
    public int address { get; set; }
    public int quantity { get; set; }
    public List<int> data { get; set; }
}

public class Root
{
    public List<MyArray> MyArray { get; set; }
}

Unfortunately the code break on this line (at the //---read back the text--- section):

Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);

I'm getting the following error:

Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ModbusJsonTest.Root' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path '', line 1, position 1.'

I tried to play a bit with the JSON format string, removing spaces, using "name":value" format instead "name":value format etc... did not work either.

I can't figure out what am I doing wrong?

I feel like I did everything by the book here...

Any code examples/suggestions I can try ?


Solution

  • The class Root is defined for only array deserialization purpose. Then we can leverage Json.NET feature. Json.NET supports built-in list deserialization for List, Array, Collection

    var myDeserializedClass = JsonConvert.DeserializeObject<List<MyArray>>();