0

I've json table like this, how I can attempd to specific data?

var json_str={ "table1":[
{"name1":"data1"},
{"name2":"data2"},
{"name3":"data3"}
],
"table2":[
{"name1":"data1"},
{"name2":"data2"},
{"name3":"data3"}
]
}   
dynamic stuff = JsonConvert.DeserializeObject(json_string); 

//I'd like attempt to data like this(for example)

var abc=stuff.table1["name1"];

this is obviously wrong, but is there any method to call the contents of the json table by name?

SOLVED: I changed my json to

var json_str={ "table1":{
"name1":"data1",
"name2":"data2",
"name3":"data3"
},
"table2":{
"name1":"data1",
"name2":"data2",
"name3":"data3"
}
} 

var abc=JsonConvert.DeserializeObject<Form1.RootObject>(json_str);  

and now I have attempt (for example) by: abc.table1.name2;

Many thanks to xdtTransform and everyone for the hints.

yaceq
  • 9
  • 1
  • https://stackoverflow.com/questions/4611031/convert-json-string-to-c-sharp-object – xdtTransform Oct 21 '19 at 08:44
  • 1
    Here is few link to help you in solving your issue. Basically you have to create the class to map your Json string. It's a 5 click thing in visual studio (edition> special past> past json as class) or 2 copy past on http://json2csharp.com. Then follow the exemple from https://www.newtonsoft.com/json/help/html/SerializingJSON.htm . – xdtTransform Oct 21 '19 at 08:47
  • Use `dynamic` from really dynamic stuff. If it's just to save 10line of auto generated code and 2 minutes then it's not a good idea. If it look `dynamic` but has the same structure then it mitgh be a `Dictionarry` or something like that. – xdtTransform Oct 21 '19 at 08:48
  • If you have controle over the Json generation it might be a good idea to switch to a array holding table1 and table2. instead of an object with many properties. This will simplify your code, a lot. – xdtTransform Oct 21 '19 at 08:54
  • as per your suggestion I generated a classes on [link]http://json2csharp.com unfortunately when I try to deserialize json by 'code' var model=JsonConvert.DeserializeObject>(json_string) I get an error: "Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Test_timer.Form1+RootObject]' because the type requires a JSON array (e.g. [1,2,3])" – yaceq Oct 21 '19 at 10:28
  • cause root object is not a list : `JsonConvert.DeserializeObject(json_string)`. Thats exactly my previous comment about Table1 and table2 beeing properties instead of object. Where do you get that json from? May we have the generation of this Json , it doesn't look handcrafted , it's just wrong. – xdtTransform Oct 21 '19 at 11:53

3 Answers3

0

Just use dot notation.

Working example:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

public class Program
{
    public static void Main()
    {
        var json_str = "{ \"table1\":[{\"name1\":\"data1\"},{\"name2\":\"data2\"},{\"name3\":\"data3\"}],\"table2\":[{\"name1\":\"data1\"},{\"name2\":\"data2\"},{\"name3\":\"data3\"}]}";
        dynamic stuff = JsonConvert.DeserializeObject(json_str);

        Console.WriteLine(stuff.table2[0].name1); // prints "data1"

    }
}

Alternative:

stuff["table2"][0]["name1"]

Why yours is not working:

var abc=stuff.table1["name1"];

You cannot access "name1" directly, because it is inside an array of objects. Take the first element with [0] and after that you can access name1.

Marlon360
  • 76
  • 4
  • Thanks for your hint, but I would prefer to avoid iterating the table by indexes because ultimately there will be a lot of data in them and I will need their names in addition to the value – yaceq Oct 21 '19 at 10:52
0

Why don't deserialize your Json to a strongly typed objects as the following sample

 class Program
    {
        static void Main(string[] args)
        {
            var json_str = "{ table1:[{name:'data1'}," +
                "{name:'data2'},{name:'data3'}]," +
                "table2:[{name:'data1'},{name:'data2'},{name:'data3'}]}";

            var collection = JsonConvert.DeserializeObject<TableCollectionObject>(json_str);

            foreach (var item in collection.table1)
            {
                Console.WriteLine(item.name);
            }

            foreach (var item in collection.table2)
            {
                Console.WriteLine(item.name);
            }

            Console.ReadLine();

        }
    }

    class TableCollectionObject
    {
        public ICollection<SingleTableObject> table1 { get; set; }
        public ICollection<SingleTableObject> table2 { get; set; }
    }

    class SingleTableObject
    {
        public string name { get; set; }
    }

Note that I've changed your Json to become a valid json object that can be parsed by Newtonsoft.Json library.

Voice Of The Rain
  • 495
  • 1
  • 8
  • 24
0

A. JObject.Parse

JObject o = JObject.Parse(json);

var name = o["table1"][0]["name1"].Value<string>();// data1
var name2 = o["table2"][2]["name3"].Value<string>();// data3

B. Dicstionary,List,Dictionary

var d = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string,List<Dictionary<string,string>>>>(json);

var nameB = d["table1"][0]["name1"]; // data1
var nameB2 = d["table2"][2]["name3"]; // data3

This is the test data I used.

var json = @"{ ""table1"":[
{""name1"":""data1""},
{""name2"":""data2""},
{""name3"":""data3""}
],
""table2"":[
{""name1"":""data1""},
{""name2"":""data2""},
{""name3"":""data3""}
]
}";

It is an usual data structure because the 1st item in the arrays has one property called name1 and the 2nd item has a single property called name2.

A more common schema is something like the following.

{
    "table1": [
        {
            "name1": "data1", "name2": "data2", "name3": "data3",
        },
        {
            "name1": "data1", "name2": "data2", "name3": "data3"
        }
    ]
}
tymtam
  • 31,798
  • 8
  • 86
  • 126
  • It's not un usual. It just feels wrong. The root object look like an array but isn't, The items in table look like rows but the value look like a miss formated dictionary. I went all the way to a custom converter on both rootobject and table item. But it's so far from the original Json, that it make no more sense as an answer. – xdtTransform Oct 21 '19 at 12:04