Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.NET: deserialize json arrays

Tags:

json

c#

json.net

I'm trying to process a JSON structure with Json.NET and encountered some issues:

My classes don't work when a JSON contains an unnamed array.

Json Example:

{
    "graph_property" : [{
            "name" : "calculation_method",
            "value" : "Arithmetic"
        }, {
            "name" : "graph_type",
            "value" : "TIME"
        }
    ],
    "measurement" : [{
            "id" : "9997666",
            "alias" : "Measurement (TxP)[IE]-Home Page - Total Time (seconds)",
            "bucket_data" : [{
                    "name" : "2013-MAR-18 12:00 AM",
                    "id" : 1,
                    "perf_data" : {
                        "value" : "2.244",
                        "unit" : "seconds"
                    },
                    "avail_data" : {
                        "value" : "99.67",
                        "unit" : "percent"
                    },
                    "data_count" : {
                        "value" : "299",
                        "unit" : "#"
                    }
                }
            ],
            "graph_option" : [{
                    "name" : "perfwarning",
                    "value" : "-",
                    "unit" : "seconds"
                }, {
                    "name" : "perfcritical",
                    "value" : "-",
                    "unit" : "seconds"
                }, {
                    "name" : "availwarning",
                    "value" : "-",
                    "unit" : "percent"
                }, {
                    "name" : "availcritical",
                    "value" : "-",
                    "unit" : "percent"
                }, {
                    "name" : "bucketsize",
                    "value" : "86400",
                    "unit" : "seconds"
                }, {
                    "name" : "rows",
                    "value" : "1",
                    "unit" : "#"
                }, {
                    "name" : "pagecomponent",
                    "value" : "Total Time",
                    "unit" : "seconds"
                }, {
                    "name" : "avg_perf",
                    "value" : "2.244",
                    "unit" : "seconds"
                }, {
                    "name" : "avg_avail",
                    "value" : "99.67",
                    "unit" : "percent"
                }, {
                    "name" : "total_datapoint_count",
                    "value" : "300",
                    "unit" : "#"
                }, {}

            ]
        }, {
            "id" : "9997666",
            "alias" : "Measurement (TxP)[IE]-Women - Total Time (seconds)",
            "bucket_data" : [{
                    "name" : "2013-MAR-18 12:00 AM",
                    "id" : 1,
                    "perf_data" : {
                        "value" : "0.979",
                        "unit" : "seconds"
                    },
                    "avail_data" : {
                        "value" : "100.00",
                        "unit" : "percent"
                    },
                    "data_count" : {
                        "value" : "299",
                        "unit" : "#"
                    }
                }
            ],
            "graph_option" : [{
                    "name" : "perfwarning",
                    "value" : "-",
                    "unit" : "seconds"
                }, {
                    "name" : "perfcritical",
                    "value" : "-",
                    "unit" : "seconds"
                }, {
                    "name" : "availwarning",
                    "value" : "-",
                    "unit" : "percent"
                }, {
                    "name" : "availcritical",
                    "value" : "-",
                    "unit" : "percent"
                }, {
                    "name" : "bucketsize",
                    "value" : "86400",
                    "unit" : "seconds"
                }, {
                    "name" : "rows",
                    "value" : "1",
                    "unit" : "#"
                }, {
                    "name" : "pagecomponent",
                    "value" : "Total Time",
                    "unit" : "seconds"
                }, {
                    "name" : "avg_perf",
                    "value" : "0.979",
                    "unit" : "seconds"
                }, {
                    "name" : "avg_avail",
                    "value" : "100.00",
                    "unit" : "percent"
                }, {
                    "name" : "total_datapoint_count",
                    "value" : "299",
                    "unit" : "#"
                }, {}

            ]
        }
    ],
    "link" : {
        "type" : "application/json",
        "href" : "http://api.website.tld?format=json",
        "rel" : "slotmetadata"
    }
}

Class for Json.NET:

using System;
using System.Collections.Generic;

namespace CAKR.Graph
{
    /// <summary>
    /// Description of KN_Graph.
    /// </summary>
    public class GraphProperty
    {
        public string name { get; set; }
        public string value { get; set; }
    }

    public class PerfData
    {
        public string value { get; set; }
        public string unit { get; set; }
    }

    public class AvailData
    {
        public string value { get; set; }
        public string unit { get; set; }
    }

    public class DataCount
    {
        public string value { get; set; }
        public string unit { get; set; }
    }

    public class BucketData
    {
        public string name { get; set; }
        public int id { get; set; }
        public PerfData perf_data { get; set; }
        public AvailData avail_data { get; set; }
        public DataCount data_count { get; set; }
    }

    public class GraphOption
    {
        public string name { get; set; }
        public string value { get; set; }
        public string unit { get; set; }
    }

    public class Measurement
    {
        public string id { get; set; }
        public string alias { get; set; }
        public List<BucketData> bucket_data { get; set; }
        public List<GraphOption> graph_option { get; set; }
    }

    public class Link
    {
        public string type { get; set; }
        public string href { get; set; }
        public string rel { get; set; }
    }

    public class RootObject
    {
        public List<GraphProperty> graph_property { get; set; }
        public List<Measurement> measurement { get; set; }
        public Link link { get; set; }
    }
}

My code:

var myObject = JsonConvert.DeserializeObject<CAKR.Graph.Measurement>(MyJsonString);

I'm not sure why I don't get an object containing the data of the "Measurment" child-array. If I insert named values, it works...

like image 718
t313 Avatar asked Mar 19 '13 18:03

t313


People also ask

What does Jsonconvert Deserializeobject do?

Deserializes the JSON to the specified . NET type. Deserializes the JSON to the specified . NET type using a collection of JsonConverter.

What is Jsonconvert?

Provides methods for converting between . NET types and JSON types. Newtonsoft.Json.

What is Jsonconvert SerializeObject C#?

SerializeObject Method (Object, Type, JsonSerializerSettings) Serializes the specified object to a JSON string using a type, formatting and JsonSerializerSettings. Namespace: Newtonsoft.Json.


1 Answers

So I was struggling for quite some time to get this working. However in the end the solution is not so difficult. Hopefully with my response I will help some people.

The solution in my case was

  1. Install JSON.net into your project by using nu.get
  2. Make your JSON object including array's in array's, etc. Be sure that the format of the object is correct! Example...

{"ProductDetail":[

  {
      "ProjectImg"    : "http://placehold.it/400x300",
      "Category"      : "Cars",
      "ProjectTitle"  : "Cars of the future",
      "ProjectDesc"   : "Test project",
      "GenSpecList"   : ["Specs1", "Specs2", "Specs3", "Specs4"],
      "OptionList"    : [{    "OptionNr"  : "1",
                              "Options"   : ["Opt1", "Opt2", "Opt3"]
                          },
                          {   "OptionNr"  : "2",
                              "Options"   : ["Opt1", "Opt2", "Opt3"]
                          },
                          {   "OptionNr"  : "3",
                              "Options"   : ["Opt1", "Opt2", "Opt3"]
                          },
                          {   "OptionNr"  : "4",
                              "Options"   : ["Opt1", "Opt2", "Opt3"]
                          },
                          {   "OptionNr"  : "5",
                              "Options"   : ["Opt1", "Opt2", "Opt3"]
                          },
                          {   "OptionNr"  : "6",
                              "Options"   : ["Opt1", "Opt2", "Opt3"]
                          }
                        ],
      "Articles"      : [{    "tileImg" : "'Images/Project/1.jpg'",
                              "tileTit" : "Title1",
                              "tileArt" : "Article text here..."
                          },
                          {
                              "tileImg" : "'Images/Project/2.jpg'",
                              "tileTit" : "Title2",
                              "tileArt" : "Article text here..."
                          },
                          {
                              "tileImg" : "'Images/Project/3.jpg'",
                              "tileTit" : "Title3",
                              "tileArt" : "Article text here..."
                          },
                          {
                              "tileImg" : "'Images/Project/4.jpg'",
                              "tileTit"   : "Title4",
                              "tileArt"   : "Article text here..."
                          }
                         ]
  }
]
}
  1. Go to json2csharp.com and copy your JSON object into the input box and click on the generate button. Copy the csharp model (this was actually the key to solve my struggle!) generated into your ViewModel.
  2. In my case the primary class of all generated classes by json2csharp.com was the RootObject and looked like below

    public class Article
    {
        public string tileImg { get; set; }
        public string tileTit { get; set; }
        public string tileArt { get; set; }
    }
    
    public class OptionList
    {
        public string OptionNr { get; set; }
        public List<string> Options { get; set; }
    }
    
    public class ProductDetail
    {
        public string ProjectImg { get; set; }
        public string Category { get; set; }
        public string ProjectTitle { get; set; }
        public string ProjectDesc { get; set; }
        public List<string> GenSpecList { get; set; }
        public List<OptionList> OptionList { get; set; }
        public List<Article> Articles { get; set; }
    }
    
    public class RootObject
    {
        public List<ProductDetail> ProductDetail { get; set; }
    }
    
  3. Then use the following code in the controller (just copied the complete file here)

    using Project.Details; //<-- this is my ViewModel namespace name
    using Newtonsoft.Json;
    using System.IO;
    using System.Threading.Tasks;
    
    namespace WebApplication.Controllers
    {
        public class JSONController : Controller
        {
            //
            // GET: /JSON/
            public async Task<ActionResult> Index()
            {
                StreamReader file = new StreamReader("C:\\Users\\YourName\\etc\\File.json");
                String json = await file.ReadToEndAsync();
    
                var Project = JsonConvert.DeserializeObject<RootObject>(json);
    
                return View();
            }
        }
    }
    

Now everything should work fine, array's in array's etc. Hope that you found my solution helpful, note I'm not a die hard programmer so if I miss things on efficency I hope to recieve some tips from you to improve this code...

Best regards, Raymond

like image 139
Raymond Avatar answered Oct 05 '22 22:10

Raymond