none
How to use System.Text.Json to parse rather complicated json data RRS feed

  • Question

  • Hello:

    I had a C# code to parse some json data with rather wired structure. One Json data is like this:

    Let’s say its name is: root_json_data:

    root_json_data:

    {"1": {"id": 1, "symbol": [{"id": 1, "name": "A", "bids": [{"price": 2.0, "amount": 100.0}], "asks": [{"price": 3.0, "amount": 100.0}]}]}} ,

    {"2": {"id": 2, "symbol": [{"id": 2, "name": "B", "bids": [{"price": 2.8, "amount": 200.0}], "asks": [{"price": 3.2, "amount": 200.0}]}]}}

    The above root_json_data can be parsed into the following 2 child json_data:

    json_data1:

    {"1": {"id": 1, "history": [], "symbol": [{"id": 1, "name": "A", "last_price": 0, "bids": [{"price": 2.0, "amount": 100.0}], "asks": [{"price": 3.0, "amount": 100.0}]}]}}

    json_data2:

    {"2": {"id": 2, "history": [], "symbol": [{"id": 2, "name": "B", "last_price": 0, "bids": [{"price": 2.8, "amount": 200.0}], "asks": [{"price": 3.2, "amount": 200.0}]}]}}

    However, trying to use a C# class to express any of the Json data is not so easy, the following is an example trying to express json_data2:

    public class RootObject

    {

    [JsonProperty("2")]

    public The2 The2 { get; set; }

    }

    public partial class The2

    {

    [JsonProperty("id")]

    public long Id { get; set; }

    [JsonProperty("symbol")]

    public Symbol[] Symbol { get; set; }

    }

    public partial class Symbol

    {

    [JsonProperty("id")]

    public long Id { get; set; }

    [JsonProperty("name")]

    public string Name { get; set; }

    [JsonProperty("bids")]

    public Ask[] Bids { get; set; }

    [JsonProperty("asks")]

    public Ask[] Asks { get; set; }

    }

    public partial class Ask

    {

    [JsonProperty("price")]

    public double Price { get; set; }

    [JsonProperty("amount")]

    public long Amount { get; set; }

    }

    }

    Using Newtonsoft.json, I had the following C# code trying to parse the Json data.

    It has to parse the children of the root object and going to 2 layers down, then I can parse the data.

    The C# code example is something like this:

     JToken jtoken_root_data = JToken.Parse(root_json_data);
     foreach (JToken level1_down in jtoken_root_data.Children())
     {
         foreach (JToken json_data in level1_down)
         {
         RootObject json_data1 = json_data.ToObject<RootObject>();
         }
    }
    

    Now, since C# has built-in Json support, I want to port my previous code using Newtonsoft.Json to use System.Text.Json to do the same job.

    I can’t figure it out, it seems rather complicated.

    PS: The actual data structure is way more complicate than my data example here, but using the same code can work.

    I am now using Visual Studio 2019 Version 16.3.1 on Windows 10 (Version 1903).

    Please advice!

    Thanks,

    Friday, September 27, 2019 10:46 PM

Answers

  • Try adjusting this:

    string json = . . . // File.ReadAllText( @"C:\MyFile1.json" ); List<MyObject> result = new List<MyObject>( ); JsonDocument doc = JsonDocument.Parse( json ); var root = doc.RootElement; for( int i = 1; ; ++i ) { JsonElement e; if( !root.TryGetProperty( i.ToString( ), out e ) ) break; MyObject obj = JsonSerializer.Deserialize<MyObject>( e.GetRawText( ) ); result.Add( obj ); } . . . public class MyObject { public int id { get; set; } public History[] history { get; set; } public Broker[] brokers { get; set; } public int settle_type { get; set; } public float min_value { get; set; } public float max_value { get; set; } public string price_precision { get; set; } public int bet_id { get; set; } public string URL { get; set; } public string name { get; set; } public float volume { get; set; } public Currency[] currencies { get; set; } public float commission { get; set; } public string user_position { get; set; } } public class History { //? } public class Broker { public int id { get; set; } public string name { get; set; } public int last_price { get; set; } public Bid[] bids { get; set; } public Ask[] asks { get; set; } } public class Bid { public float price { get; set; } public float amount { get; set; } } public class Ask { public float price { get; set; } public float amount { get; set; } }

    public class Currency
    {
     //?
    }


    For money, use decimal type.

    The History and Currency classes cannot be defined from available sample data.
    • Edited by Viorel_MVP Saturday, September 28, 2019 3:07 PM
    • Marked as answer by zydjohn Saturday, September 28, 2019 7:09 PM
    Saturday, September 28, 2019 3:01 PM

All replies

  • Hello,

    The first step to asking for assistance is to properly format your post which it's not at this point.

    The sample json needs to be in a code block separated from text, same goes for the C# code.


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Saturday, September 28, 2019 11:30 AM
    Moderator
  • Hello:

    I can rewrite my post using the code to show the Json data.
    I had a C# code to parse some json data with rather wired structure. One Json data is like this:
    Let’s say its name is: root_json_data:

    root_json_data:
    {"1": {"id": 1, "symbol": [{"id": 1, "name": "A", "bids": [{"price": 2.0, "amount": 100.0}], "asks": [{"price": 3.0, "amount": 100.0}]}]}} ,
    {"2": {"id": 2, "symbol": [{"id": 2, "name": "B", "bids": [{"price": 2.8, "amount": 200.0}], "asks": [{"price": 3.2, "amount": 200.0}]}]}}

    Now, since C# has built-in Json support, I want to use System.Text.Json to parse the above Json data to get an array of Json objects.
    Please advice!
    Thanks,

    PS: the issue for formatting the post is: Json data is not any programming language in the list.

    Saturday, September 28, 2019 11:45 AM
  • Since this does not seem to be a fully valid JSON, the parsing becomes difficult.

    Is it possible to a have a different format, such as:

       { "root_json_data": { "1": { . . . }, "2": { . . . } } }

    or

       { "root_json_data": [ { "1": { . . . } }, { "2": { . . . }  } ] } ?

    Confirm the real format of your JSON string or file.

    Saturday, September 28, 2019 12:40 PM
  • Hello:

    Sorry, there were something wrong with the example data.  Now, I can provide a real Json data.  However, I can't change the format of the data, as it was grabbed from a web site.

    {
       "1":{
          "id":1,
          "history":[
    
          ],
          "brokers":[
             {
                "id":4601,
                "name":"A_Plus",
                "last_price":0,
                "bids":[
                   {
                      "price":1.917,
                      "amount":364.11
                   }
                ],
                "asks":[
                   {
                      "price":2.1,
                      "amount":334.11
                   }
                ]
             },
             {
                "id":4602,
                "name":"A_Minus",
                "last_price":0,
                "bids":[
    
                ],
                "asks":[
    
                ]
             }
          ],
          "settle_type":0,
          "min_value":0.0,
          "max_value":0.0,
          "price_precision":"6",
          "bet_id":1811,
          "URL":"/market/295/",
          "name":"Company295",
          "volume":0.0,
          "currencies":[
    
          ],
          "commission":0.0025,
          "user_position":""
       },
       "2":{
          "id":2,
          "history":[
    
          ],
          "brokers":[
             {
                "id":4621,
                "name":"B_Plus",
                "last_price":0,
                "bids":[
                   {
                      "price":1.74,
                      "amount":676.11
                   }
                ],
                "asks":[
                   {
                      "price":1.863,
                      "amount":581.11
                   }
                ]
             },
             {
                "id":4622,
                "name":"B_Minus",
                "last_price":0,
                "bids":[
    
                ],
                "asks":[
    
                ]
             }
          ],
          "settle_type":0,
          "min_value":0.0,
          "max_value":0.0,
          "price_precision":"6",
          "bet_id":1812,
          "URL":"/market/set2/",
          "name":"CompanySet2",
          "volume":0.0,
          "currencies":[
    
          ],
          "commission":0.0025,
          "user_position":""
       }
    }

    I checked with some web site, the Json format is valid this time.

    Thanks,

    Saturday, September 28, 2019 2:00 PM
  • Try adjusting this:

    string json = . . . // File.ReadAllText( @"C:\MyFile1.json" ); List<MyObject> result = new List<MyObject>( ); JsonDocument doc = JsonDocument.Parse( json ); var root = doc.RootElement; for( int i = 1; ; ++i ) { JsonElement e; if( !root.TryGetProperty( i.ToString( ), out e ) ) break; MyObject obj = JsonSerializer.Deserialize<MyObject>( e.GetRawText( ) ); result.Add( obj ); } . . . public class MyObject { public int id { get; set; } public History[] history { get; set; } public Broker[] brokers { get; set; } public int settle_type { get; set; } public float min_value { get; set; } public float max_value { get; set; } public string price_precision { get; set; } public int bet_id { get; set; } public string URL { get; set; } public string name { get; set; } public float volume { get; set; } public Currency[] currencies { get; set; } public float commission { get; set; } public string user_position { get; set; } } public class History { //? } public class Broker { public int id { get; set; } public string name { get; set; } public int last_price { get; set; } public Bid[] bids { get; set; } public Ask[] asks { get; set; } } public class Bid { public float price { get; set; } public float amount { get; set; } } public class Ask { public float price { get; set; } public float amount { get; set; } }

    public class Currency
    {
     //?
    }


    For money, use decimal type.

    The History and Currency classes cannot be defined from available sample data.
    • Edited by Viorel_MVP Saturday, September 28, 2019 3:07 PM
    • Marked as answer by zydjohn Saturday, September 28, 2019 7:09 PM
    Saturday, September 28, 2019 3:01 PM