Home > OS >  How to deserailise JSON Object in C# Without knowing structure
How to deserailise JSON Object in C# Without knowing structure

Time:03-24

Is it possible to take a JSON object in C# that I read from from another source and convert the contents to files. The problem is I don't know the structure of the incoming objects.

So far I've got this:

 var response = await client.GetAsync("https://blahblah/creds"  
     "?ApiKey="   textBox_password.Text  
     "&deviceId="   deviceId  
     "&modelNum="   modelNum);

 var res = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
 var resJson = JsonConvert.DeserializeObject(res);
 this.textBox_Stream.AppendText("responseBody = "   resJson   "\r\n"); 

Which gives me:

responseBody = {
  "statusCode": 200,
  "body": {
    "modelNum": "42",
    "creds": "[{\"deviceid.txt\":\"4DA23E\",\"pac.txt\":\"580795498743\"}]",
    "deviceId": "4DA23E"
  }
}

What I want to do is create a folder called 4DA23E and place one file inside it for each entry in the creds object.

device.txt will contain 4DA23E pac.tct will contain 580795498743

etc. I can't figure out a dynamic way to extract the stuff I need. Goes without saying, I am not a C# programmer! So, please be kind.

CodePudding user response:

Don't use JsonConvert.DeserializeObject. That's best when you know the schema of the JSON object and you've made a corresponding C# model.

First, parse the outer response JSON

var res = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
JObject resJson = JObject.Parse(res);

Now pull out the value of the "creds" property and re-parse it.

var credsJsonRaw = resJson["body"]["creds"].Value<string>();
JArray credsJson = JArray.Parse(credsJsonRaw);

Now you can loop through each object in the array, and each property in each object.

foreach (JObject obj in credsJson)
{
    foreach (JProperty prop in obj.Properties)
    {
        Console.WriteLine($"Name = {prop.Name}");
        Console.WriteLine($"Value = {prop.Value.Value<string>()}");
    }
}

For your example, this prints

Name = deviceid.txt
Value = 4DA23E
Name = pac.txt
Value = 580795498743

CodePudding user response:

One way to deserialise the following json is in two stages. This is because 'creds' is a string.

{
   "statusCode": 200,
   "body": {
     "modelNum": "42",
     "creds": "[{\"deviceid.txt\":\"4DA23E\",\"pac.txt\":\"580795498743\"}]",
     "deviceId": "4DA23E"
   }
 }

Here's an example of how to do it. If you're not .NET6 change 'record' to 'class' and if you don't use nullable reference types (on by default in .NET6) remove the appropriate question marks in property definitions.

using System.Text.Json;
using System.Text.Json.Serialization;

var json = File.ReadAllText("data.json");

var o = JsonSerializer.Deserialize<Outer>(json);

if(o?.Body?.Creds == null)
{
    throw new Exception("Bad data");
}

var credList = JsonSerializer.Deserialize<List<Dictionary<string, string>>>(o.Body.Creds);

if(credList == null)
{      
    throw new Exception("Bad data");
}

foreach( var e in credList)
    foreach( var kvp in e)
        Console.WriteLine($"{kvp.Key} : {kvp.Value}");

record Outer {
     [JsonPropertyName("staticCode")]
    public int? StaticCode {get; set;}

    [JsonPropertyName("body")]
    public Body? Body {get; set;}
}

record Body {

    [JsonPropertyName("creds")]
    public string? Creds {get; set;}
}

This prints

deviceid.txt : 4DA23E
pac.txt : 580795498743
  •  Tags:  
  • c#
  • Related