AGlasencnik
AGlasencnik

Reputation: 159

How to deserialize nested JSON in C#

I know this type of question has probably been asked before, but I when I tried it it didn't quite work. I am new to working with jsons in C#. So I have a JSON file (example from the file is shorter than in real one), from which I want to get values. Values I need are in 'languages' array.

There is a great solution from getting data from the array on the website:
https://www.newtonsoft.com/json/help/html/DeserializeDataSet.htm

But, I have a problem because there is a 'Result' attribute, and I don't know how to go through it. Also there are a lot of attributes in the top of the json ('Headers') Which I don't need but i think I still need to include them in my code?. It would really help if someone could please send me some tips or a solution on how to do it. There will also be an incomplete example of code, which gives errors. Also if any one of you could also reply with maybe a good video on YouTube or website about Json.net except from the official documentation, that would be amazing. Thanks

Json:

{
  "StatusCode": 200,
  "Headers": {
    "X-XSS-Protection": "1; mode=block",
    "X-Content-Type-Options": "nosniff",
    "Content-Security-Policy": "default-src 'none'",
    "Cache-Control": "no-store, no-cache",
    "Pragma": "no-cache",
    "Strict-Transport-Security": "max-age=31536000; includeSubDomains;",
    "x-dp-watson-tran-id": "0cf1366a-5bd0-4210-a291-93a30ea0ac62",
    "X-Request-ID": "0cf1366a-5bd0-4210-a291-93a30ea0ac62",
    "x-global-transaction-id": "0cf1366a-5bd0-4210-a291-93a30ea0ac62",
    "Server": "watson-gateway",
    "X-EdgeConnect-MidMile-RTT": "5",
    "X-EdgeConnect-Origin-MEX-Latency": "92",
    "Date": "Wed, 25 Aug 2021 13:21:23 GMT",
    "Connection": "keep-alive"
  },
  "Result": {
    "languages": [
      {
        "language": "af",
        "language_name": "Afrikaans",
        "native_language_name": "Afrikaans",
        "country_code": "ZA",
        "words_separated": true,
        "direction": "left_to_right",
        "supported_as_source": false,
        "supported_as_target": false,
        "identifiable": true
      },
      {
        "language": "ar",
        "language_name": "Arabic",
        "native_language_name": "العربية",
        "country_code": "AR",
        "words_separated": true,
        "direction": "right_to_left",
        "supported_as_source": true,
        "supported_as_target": true,
        "identifiable": true
      },
      {
        "language": "az",
        "language_name": "Azerbaijani",
        "native_language_name": "آذربایجان دیلی",
        "country_code": "AZ",
        "words_separated": true,
        "direction": "right_to_left",
        "supported_as_source": false,
        "supported_as_target": false,
        "identifiable": true
      }
    ]
}

My incomplete code:

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

namespace WorkingWithFiles
{
    class FullJson
    {
        public int StatusCode { get; set; }
        public Dictionary<string, List<Headers>> Headers { get; set; }
        public Dictionary<string, List<Languages>> Result { get; set; }

    }

    class Headers
    {
        public string xXssProtection { get; set; }
        public string xContentTypeOptions { get; set; }
        public string contentTypeOptions { get; set; }
        public string cacheControl { get; set; }
        public string pragma { get; set; }
        public string strictTransportSecurity { get; set; }
        public string xDpWatsonTranId { get; set; }
        public string xRequestId { get; set; }
        public string xGlobalTransactionId { get; set; }
        public string server { get; set; }
        public string xEdgeConnectMidMileRTT { get; set; }
        public string xEdgeConnectOriginMEXLatency { get; set; }
        public string date { get; set; }
        public string connection { get; set; }
    }

    class Languages
    {

    }

class Program
    {
        static void Main(string[] args)
        {
            string root = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            string path = root + @"\SubtitleTranslator\LanguagesList.json";

            FullJson fullJson = JsonConvert.DeserializeObject<FullJson>(File.ReadAllText(path));
            Console.WriteLine("Status code: " + fullJson.StatusCode);





        }
    }
}

Upvotes: 2

Views: 5147

Answers (2)

Serge
Serge

Reputation: 43969

All code was tested using VS2019 and working properly.

The simpliest way will be

var root =Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var path = root + @"\SubtitleTranslator\LanguagesList.json";
 var json = File.ReadAllText(path);
var jsonDeserialized = JsonConvert.DeserializeObject<Root>(json);
List<Language> languages = null;
if( jsonDeserialized.StatusCode== 200) languages=jsonDeserialized.Result.languages;

or if you don't need any data except languages, try this code

var languages= JObject.Parse(json)["Result"]["languages"].ToObject<Language[]>();

in this case you will need only Language class

OUTPUT (in both cases)

[{"language":"af","language_name":"Afrikaans","native_language_name":"Afrikaans","country_code":"ZA","words_separated":true,"direction":"left_to_right","supported_as_source":false,"supported_as_target":false,"identifiable":true},
{"language":"ar","language_name":"Arabic","native_language_name":"العربية","country_code":"AR","words_separated":true,"direction":"right_to_left","supported_as_source":true,"supported_as_target":true,"identifiable":true},
{"language":"az","language_name":"Azerbaijani","native_language_name":"آذربایجان دیلی","country_code":"AZ","words_separated":true,"direction":"right_to_left","supported_as_source":false,"supported_as_target":false,"identifiable":true}]

Update

you can test it using Console.WriteLine

foreach (var lg in languages)
{
Console.WriteLine($"Language Name: {lg.native_language_name}, Coutry Code: {lg.country_code}");
        
}

Language class

public class Language
{
    public string language { get; set; }
    public string language_name { get; set; }
    public string native_language_name { get; set; }
    public string country_code { get; set; }
    public bool words_separated { get; set; }
    public string direction { get; set; }
    public bool supported_as_source { get; set; }
    public bool supported_as_target { get; set; }
    public bool identifiable { get; set; }
}

another classes (if needed)

public class Root
{
    public int StatusCode { get; set; }
    public Headers Headers { get; set; }
    public Result Result { get; set; }
}
public class Headers
{
    [JsonProperty("X-XSS-Protection")]
    public string XXSSProtection { get; set; }

    [JsonProperty("X-Content-Type-Options")]
    public string XContentTypeOptions { get; set; }

    [JsonProperty("Content-Security-Policy")]
    public string ContentSecurityPolicy { get; set; }

    [JsonProperty("Cache-Control")]
    public string CacheControl { get; set; }
    public string Pragma { get; set; }

    [JsonProperty("Strict-Transport-Security")]
    public string StrictTransportSecurity { get; set; }

    [JsonProperty("x-dp-watson-tran-id")]
    public string XDpWatsonTranId { get; set; }

    [JsonProperty("X-Request-ID")]
    public string XRequestID { get; set; }

    [JsonProperty("x-global-transaction-id")]
    public string XGlobalTransactionId { get; set; }
    public string Server { get; set; }

    [JsonProperty("X-EdgeConnect-MidMile-RTT")]
    public string XEdgeConnectMidMileRTT { get; set; }

    [JsonProperty("X-EdgeConnect-Origin-MEX-Latency")]
    public string XEdgeConnectOriginMEXLatency { get; set; }
    public string Date { get; set; }
    public string Connection { get; set; }
}


public class Result
{
    public List<Language> languages { get; set; }
}
````
    

Upvotes: 2

Spencer Bench
Spencer Bench

Reputation: 645

If all you need is the contents of the languages array, then use Json.NET's LINQ to JSON feature:

class LangInfo {
    public string language { get; set; }
    public string language_name { get; set; }
    public string native_language_name { get; set; }
    ...
}
var langs = JObject.Parse(json)["Result"]["languages"].Children()
    .Select(token => token.ToObject<LangInfo>()).ToList();

Upvotes: 0

Related Questions