How to deserialize and get into model class nested Json ?

sassKsassK USMember ✭✭

This I the json string {"usermachine":[{"employeeid":"EMP002 ","employeename":"EMP002 NAME","machineid":"E0138","machinename":"FOS","iscleaning":1,"isperforming":1,"isverifying":1},{"cInterval":112,"cCleanOperationMaxTime":86400,"cPerformOperationMaxTime":300},{"oSequenceID":2,"oCompletedOperation":1,"oComplOperStartTime":1555384452,"oCompOperEndndTime":1555384652,"oOperationToContinue":2},{"pinterval":[{"pLocationNumber":1,"pLocationName":"TestLoc1","pLocationInterval":12},{"pLocationNumber":2,"pLocationName":"TestLoc2","pLocationInterval":1121}]}]}

Json2Csharp class
public class Pinterval
{
public int pLocationNumber { get; set; }
public string pLocationName { get; set; }
public int pLocationInterval { get; set; }
}

public class Usermachine
{
public string employeeid { get; set; }
public string employeename { get; set; }
public string machineid { get; set; }
public string machinename { get; set; }
public int iscleaning { get; set; }
public int isperforming { get; set; }
public int isverifying { get; set; }
public int? cInterval { get; set; }
public int? cCleanOperationMaxTime { get; set; }
public int? cPerformOperationMaxTime { get; set; }
public int? oSequenceID { get; set; }
public int? oCompletedOperation { get; set; }
public int? oComplOperStartTime { get; set; }
public int? oCompOperEndndTime { get; set; }
public int? oOperationToContinue { get; set; }
public List pinterval { get; set; }
}

public class RootObject
{
public List usermachine { get; set; }
}

This is my models.class
public class Pinterval
{
public int pLocationNumber { get; set; }
public string pLocationName { get; set; }
public int pLocationInterval { get; set; }
}

public class Usermachine
{
    public string employeeid { get; set; }
    public string employeename { get; set; }
    public string machineid { get; set; }
    public string machinename { get; set; }
    public int iscleaning { get; set; }
    public int isperforming { get; set; }
    public int isverifying { get; set; }
    public int cInterval { get; set; }
    public int cCleanOperationMaxTime { get; set; }
    public int cPerformOperationMaxTime { get; set; }
    public int oSequenceID { get; set; }
    public int oCompletedOperation { get; set; }
    public int oComplOperStartTime { get; set; }
    public int oCompOperEndndTime { get; set; }
    public int oOperationToContinue { get; set; }
    public List<Pinterval> pinterval { get; set; }

}

public class UsermachineList
{
    public List<Usermachine> usermachine { get; set; }
}

My Code to retrieve data works with the Usermachine structure but not with the pinterval list.
my code :
var client = new System.Net.Http.HttpClient();

            var response = await client.GetAsync(linkremoved as I am getting a message you have to be around for a while);
            string usersJson = await response.Content.ReadAsStringAsync();
            UsermachineList objUsermachineList = new UsermachineList();
            if (usersJson != "")
            {
                //Converting JSON Array Objects into generic list  
                objUsermachineList = JsonConvert.DeserializeObject<UsermachineList>(usersJson);
                //partially original changed products to productsJason
                // objProductList = JsonConvert.DeserializeAnonymousType(productsJason);
                //// var prds = JsonConvert.DeserializeObject(productsJason);

            }
            //Binding listview with server response    

           // listviewProducts.ItemsSource = objUsermachineList.usermachine;
            foreach (var usm in objUsermachineList.usermachine)
            {
                if (usm != null)
                {
                    string data2Display = usm.employeename.ToString() + " / " + usm.employeeid.ToString() + " / " + usm.machinename.ToString();
                    string pintDisplay = "";
                    foreach (var pint in usm.pinterval) // *** This is where I get issues. pinterval is null
                    {
                        if (pint != null)
                        {
                            pintDisplay = pint.pLocationInterval.ToString() + " / " + pint.pLocationName.ToString() + " / " + pint.pLocationInterval.ToString();

                        }
                        else
                        {
                            break;
                        }
                    }
                    await DisplayAlert("UserMachine", data2Display, "OK");
                    await DisplayAlert("Interval", pintDisplay, "OK");

Hope someone can throw some light and share your ideas.
Thanks in advance

Answers

  • JoeMankeJoeManke USMember ✭✭✭✭✭
    edited April 16

    I think your JSON is a mess that shouldn't all be deserialized into a single class as-is, but as far as fixing what you have just null-check usm.pinterval before trying to iterate through it.

    Edit: Formatted JSON for the benefit of anyone who wants to be able to read it:

    {
      "usermachine": 
      [    
        {
          "employeeid": "EMP002 ",
          "employeename": "EMP002 NAME",
          "machineid": "E0138",
          "machinename": "FOS",
          "iscleaning": 1,
          "isperforming": 1,
          "isverifying": 1
        },    
        {
          "cInterval": 112,
          "cCleanOperationMaxTime": 86400,
          "cPerformOperationMaxTime": 300
        },    
        {
          "oSequenceID": 2,
          "oCompletedOperation": 1,
          "oComplOperStartTime": 1555384452,
          "oCompOperEndndTime": 1555384652,
          "oOperationToContinue": 2
        },    
        {
          "pinterval": 
          [        
            {
              "pLocationNumber": 1,
              "pLocationName": "TestLoc1",
              "pLocationInterval": 12
            },        
            {
              "pLocationNumber": 2,
              "pLocationName": "TestLoc2",
              "pLocationInterval": 1121
            }
          ]
        }
      ]
    }
    
  • sassKsassK USMember ✭✭

    thanks for the response joe. Can you please clarify on your reply please.
    I think your JSON is a mess that shouldn't all be deserialized into a single class as-is, -- Actually that is having pinterval as a nested list. Do you mean to say that it should not be a single class. I can change that. For 1 C interval there can be upto 30 pIntervals. Since you say it should not be single class, should I get the pInterval as a separate GetAsync or can 1 single GetAsyn request get both classes ? ( I am sorry I am asking probably a most novice question ).

    but as far as fixing what you have just null-check usm.pinterval before trying to iterate through it. : I do not get even the first data. There is data in pinterval but the statement shows it as null

  • ColeXColeX Member, Xamarin Team Xamurai

    Check the formatted json

    {
      "usermachine": 
      [    
        {
          "employeeid": "EMP002 ",
          "employeename": "EMP002 NAME",
          "machineid": "E0138",
          "machinename": "FOS",
          "iscleaning": 1,
          "isperforming": 1,
          "isverifying": 1
        },    
        {
          "cInterval": 112,
          "cCleanOperationMaxTime": 86400,
          "cPerformOperationMaxTime": 300
        },    
        {
          "oSequenceID": 2,
          "oCompletedOperation": 1,
          "oComplOperStartTime": 1555384452,
          "oCompOperEndndTime": 1555384652,
          "oOperationToContinue": 2
        },    
        {
          "pinterval": 
          [        
            {
              "pLocationNumber": 1,
              "pLocationName": "TestLoc1",
              "pLocationInterval": 12
            },        
            {
              "pLocationNumber": 2,
              "pLocationName": "TestLoc2",
              "pLocationInterval": 1121
            }
          ]
        }
      ]
    }
    

    pinterval belongs to the forth object , the first three one doesn't have pinterval , so the value is null.

    Add this line before retrieving usm.pinterval.

    if(usm.pinterval ! = null){
        foreach (var pint in usm.pinterval) // *** This is where I get issues. pinterval is null
                        {
                            if (pint != null)
                            {
                                pintDisplay = pint.pLocationInterval.ToString() + " / " + pint.pLocationName.ToString() + " / " + pint.pLocationInterval.ToString();
    
                            }
                            else
                            {
                                break;
                            }
                        }
    }
    
  • sassKsassK USMember ✭✭

    After reading your reply I modified my RESt API (using scriptcase / php) . The Json string comes as follows now
    {"usermachine":
    {
    "employeeid":"EMP002 ",
    "employeename":"EMP002 NAME",
    "machineid":"E0138",
    "machinename":"FOS",
    "iscleaning":1,
    "isperforming":1,
    "isverifying":1,"cSeqno":1,
    "cInterval":112,"cCleanOperationMaxTime":86400,
    "cPerformOperationMaxTime":300,"oSequenceID":0,
    "oCompletedOperation":0,
    "oComplOperStartTime":0,
    "oCompOperEndndTime":0,
    "oOperationToContinue":1
    }
    }

    I have removed the pinterval sending it separately as follows
    {
    "pinterval":
    [
    {
    "pLocationNumber":1,
    "pLocationName":"TestLoc1",
    "pLocationInterval":12
    },
    {
    "pLocationNumber":2,
    "pLocationName":"TestLoc2",
    "pLocationInterval":1121
    }
    ]
    }
    the classes are as developed by json2Csharp (not pasting here to save space and make it readable)

    Now the following is the code
    var client = new System.Net.Http.HttpClient();
    var response = await client.GetAsync("http://127.0.0.1:9090/lcappi/machineinfo/?uid=EMP002&mid=E0138");
    var usersJson = await response.Content.ReadAsStringAsync();
    Models.Usermachine objUsermacList = new Models.Usermachine();
    Console.WriteLine(usersJson);
    if (usersJson != "")
    {
    //Converting JSON Array Objects into generic list
    objUsermacList = JsonConvert.DeserializeObject<Models.Usermachine>(usersJson);
    string data2Display = ChekReturn(objUsermacList.employeename) + " / " + ChekReturn(objUsermacList.employeeid) + " / " + ChekReturn(objUsermacList.machineid) + " / " + ChekReturn(objUsermacList.machinename);
    data2Display = data2Display + " Cint " + ChekReturn(objUsermacList.cInterval) + " CLMAX " + ChekReturn(objUsermacList.cCleanOperationMaxTime) + " PMAX " + ChekReturn(objUsermacList.cPerformOperationMaxTime);
    data2Display = data2Display + " seq " + ChekReturn(objUsermacList.oSequenceID) + " Done " + ChekReturn(objUsermacList.isverifying) + ChekReturn(objUsermacList.isperforming);
    Console.WriteLine(data2Display);

                }  //Above Returns /   /   /   Cint 0 CLMAX 0 PMAX 0 seq 0 Done 00
    
                using (HttpClient clnt = new HttpClient())
                {
                    clnt.DefaultRequestHeaders.Accept.Add(
                        new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
    
    
                    var respnse = clnt.GetAsync("http://127.0.0.1:9090/lcappi/machineinfo/?uid=EMP002&mid=E0138").Result;
    
                    string content = respnse.Content.ReadAsStringAsync().Result;
                    Console.WriteLine(content);  // Writes out the jsonstring as is
    
                    Models.UserMachineList usermachinelist = new Models.UserMachineList();
    
                    if (content != "")
                    {
                        usermachinelist = JsonConvert.DeserializeObject<Models.UserMachineList>(content);
                        foreach (var usm in usermachinelist.usermachine)
                        {
                            string data2Display = ChekReturn(usm.employeename) + " / " + ChekReturn(usm.employeeid) + " / " + ChekReturn(usm.machineid) + " / " + ChekReturn(usm.machinename);
                            data2Display = data2Display + " Cint " + ChekReturn(usm.cInterval) + " CLMAX " + ChekReturn(usm.cCleanOperationMaxTime) + " PMAX " + ChekReturn(usm.cPerformOperationMaxTime);
                            data2Display = data2Display + " seq " + ChekReturn(usm.oSequenceID) + " Done " + ChekReturn(usm.isverifying) + ChekReturn(usm.isperforming);
                            Console.WriteLine(data2Display);
    
                        } // This gives error saying expecting array
    
                    } //if (content != "")
                } // using (HttpClient clnt = new HttpClient())
                using (HttpClient clnt = new HttpClient())
                {
                    clnt.DefaultRequestHeaders.Accept.Add(
                        new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
    
    
                    var respnse = clnt.GetAsync("http://127.0.0.1:9090/lcappi/pinterval/?cSeqNo=1&mid=E0138").Result;
    
                    string content = respnse.Content.ReadAsStringAsync().Result;
                    Console.WriteLine(content);  // Writes out the jsonstring as is
                    //Console.ReadLine();
                   // Models.PintervalList pIntervalList = new Models.PintervalList();
                    Models.PintervalList pIntervalList = new Models.PintervalList();
                    //Models.Usermachine uml = new Models.Usermachine();
                    if (content != "")
                    {
    
                        //Converting JSON Array Objects into generic list  
                        pIntervalList = JsonConvert.DeserializeObject<Models.PintervalList>(content);
                        //partially original changed products to productsJason
                        // objProductList = JsonConvert.DeserializeAnonymousType(productsJason);
                        //// var prds = JsonConvert.DeserializeObject(productsJason);
                        foreach (var usm in pIntervalList.pinterval)
                        {
                            string data2Display = ChekReturn(usm.pLocationNumber) + " / " + ChekReturn(usm.pLocationName) + " / " + ChekReturn(usm.pLocationInterval) + " / " ;
                            Console.WriteLine(data2Display);
                        }
    
                    } //if (content != "")
    
    
                } // using (HttpClient clnt = new HttpClient())
    

    serJson String value {"usermachine":{"employeeid":"EMP002 ","employeename":"EMP002 NAME","machineid":"E0138","machinename":"FOS","iscleaning":1,"isperforming":1,"isverifying":1,"cSeqno":1,"cInterval":112,"cCleanOperationMaxTime":86400,"cPerformOperationMaxTime":300,"oSequenceID":0,"oCompletedOperation":0,"oComplOperStartTime":0,"oCompOperEndndTime":0,"oOperationToContinue":1}}

    ? objUsermacList
    {WindowsFormsApplication1.Models.Usermachine}
    cCleanOperationMaxTime: 0
    cInterval: 0
    cPerformOperationMaxTime: 0
    employeeid: null
    employeename: null
    iscleaning: 0
    isperforming: 0
    isverifying: 0
    machineid: null

    Following error when i am using the foreach loop
    Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[WindowsFormsApplication1.Models+Usermachine]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

    To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

    Path 'usermachine.employeeid', line 1, position 29.

  • sassKsassK USMember ✭✭

    I finally changed the json string output from the rest api
    {"usermachine":
    [
    {
    "employeeid":"EMP002 ",
    "employeename":"EMP002NAME",
    "machineid":"E0138",
    "machinename":"FOS",
    "iscleaning":1,
    "isperforming":1,
    "isverifying":1,
    "cSeqno":1,"cInterval":112,
    "cCleanOperationMaxTime":86400,
    "cPerformOperationMaxTime":300,
    "oSequenceID":0,
    "oCompletedOperation":0,
    "oComplOperStartTime":0,
    "oCompOperEndndTime":0,
    "oOperationToContinue":1
    }
    ]
    }
    I am making a separate Get for the pinterval so it is now a separate list and not a nested list of the above
    {"pinterval":
    [
    {
    "pLocationNumber":1,
    "pLocationName":"TestLoc1",
    "pLocationInterval":12
    },
    {
    "pLocationNumber":2
    ,"pLocationName":"TestLoc2",
    "pLocationInterval":1121
    }
    ]
    }
    The Xamarin code as follows
    if (NetworkCheck.IsInternet())
    {
    string hostmi = NetworkCheck.ipAddr() + App.macapi; // + "uid=EMP002&mid=E0138";
    string hostpi = NetworkCheck.ipAddr() + App.intapi; // + "cSeqNo=1&mid=E0138";

                string data2Display = "";
                using (HttpClient client = new HttpClient())  // machineinfo process
                {
                    client.DefaultRequestHeaders.Accept.Add(
                        new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
    
    
                    var respnse = client.GetAsync("http://10.0.2.2:9090/lcappi/machineinfo/?uid=EMP002&mid=E0138").Result;
    
                    string content = respnse.Content.ReadAsStringAsync().Result;
                    //Console.WriteLine(content);  // Writes out the jsonstring as is
    
                    UserMachineList usermachinelist = new UserMachineList();
    
                    if (content != "")
                    {
                        usermachinelist = JsonConvert.DeserializeObject<UserMachineList>(content);
                        //var umlist = JsonConvert.DeserializeObject<Models.UserMachineList>(content);
                        foreach (var usm in usermachinelist.usermachine)
                        // foreach (var usm in umlist)
                        {
                            data2Display = CHK.Vld(usm.employeename) + " / " + CHK.Vld(usm.employeeid) + " / " + CHK.Vld(usm.machineid) + " / " + CHK.Vld(usm.machinename);
                            data2Display = data2Display + " Cint " + CHK.Vld(usm.cInterval) + " CLMAX " + CHK.Vld(usm.cCleanOperationMaxTime) + " PMAX " + CHK.Vld(usm.cPerformOperationMaxTime);
                            data2Display = data2Display + " seq " + CHK.Vld(usm.oSequenceID) + " Done " + CHK.Vld(usm.isverifying) + CHK.Vld(usm.isperforming);
                            //  Console.WriteLine(data2Display);
                            App.mclIntervalList[0] = 0;
                            if (CHK.Vld(usm.cInterval) != " ") App.mclIntervalList[1] = usm.cInterval;
                            if (CHK.Vld(usm.cCleanOperationMaxTime)!=" ") App.mOperationMaxTime = usm.cCleanOperationMaxTime;
                            if (CHK.Vld(usm.cPerformOperationMaxTime) != " ") App.miSequenceMaxTime = usm.cPerformOperationMaxTime;
                            if (CHK.Vld(usm.oOperationToContinue) != " ") nextOperation = usm.oOperationToContinue;
    
                        }  //foreach (var usm in usermachinelist.usermachine)
                    } //if (content != "")
                } // using (HttpClient clnt = new HttpClient()) // machineinfo process
                using (HttpClient clnt = new HttpClient()) //pinterval
                {
                    clnt.DefaultRequestHeaders.Accept.Add(
                        new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
    
    
                    var respnse = clnt.GetAsync("http://10.0.2.2:9090/lcappi/pinterval/?cSeqNo=1&mid=E0138").Result;
    
                    string content = respnse.Content.ReadAsStringAsync().Result;
                    //  Console.WriteLine(content);  // Writes out the jsonstring as is
    
                    PintervalList pIntervalList = new PintervalList();
    
                    if (content != "")
                    {
    
                        //Converting JSON Array Objects into generic list  
                        pIntervalList = JsonConvert.DeserializeObject<PintervalList>(content);
                        int i = 0;
                       // int[] interv = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                        foreach (var usm in pIntervalList.pinterval)
                        {
                            data2Display = data2Display + CHK.Vld(usm.pLocationNumber) + " / " + CHK.Vld(usm.pLocationName) + " / " + CHK.Vld(usm.pLocationInterval) + " / ";
                            if (CHK.Vld(usm.pLocationInterval) != " ")
                            {
                                App.mprIntervalList[i + 1] = (int)usm.pLocationInterval;
                                i++;
                                App.mprTotalLocations2Scan =i;
                            }
    
                        }
    
                       // DisplayAlert("JSONDATA ", data2Display, "Ok");
                    } //if (content != "")
    
    
                } // using (HttpClient clnt = new HttpClient())  //pinterval
    
            }
            else
            {
                await DisplayAlert("JSONParsing", "No network is available.", "Ok");
            }
    

    The JsonModel Class
    public class JsonModel
    {
    public class Pinterval
    {
    public int pLocationNumber { get; set; }
    public string pLocationName { get; set; }
    public int pLocationInterval { get; set; }
    }
    public class PintervalList
    {
    public List pinterval { get; set; }
    }
    [JsonObject]
    public class Usermachine
    {
    public string employeeid { get; set; }
    public string employeename { get; set; }
    public string machineid { get; set; }
    public string machinename { get; set; }
    public int iscleaning { get; set; }
    public int isperforming { get; set; }
    public int isverifying { get; set; }
    public int cInterval { get; set; }
    public int cCleanOperationMaxTime { get; set; }
    public int cPerformOperationMaxTime { get; set; }
    public int oSequenceID { get; set; }
    public int oCompletedOperation { get; set; }
    public int oComplOperStartTime { get; set; }
    public int oCompOperEndndTime { get; set; }
    public int oOperationToContinue { get; set; }

        }
        public class UserMachineList
        {
            public List<Usermachine> usermachine { get; set; }
        }
    }
    

    The output is fine (only checked on the immediate window by ? data2Display). I request help from some one kind enought to a cross check and let me know if there is any mistake or if this is the right way . Also, I am not able to use the await part for the get.Async, will be most thankful for your help there.

    Thanks in advance.

  • ColeXColeX Member, Xamarin Team Xamurai

    Could you share a basic sample ?

Sign In or Register to comment.