0

In my C# code I am calling an endpoint which sends back the structure something similar to this

{       
       "name":"test",
        "clients": {
            "client1": {"id": "1", "count": "41"},
            "client2": {"name": "testName"},
            "client3": {"CustomerID": "a1", "internalID": "testID"}
        }
}

I need to convert this to a C# object and then iterate through the "clients". The problem is that beforehand I do not know the client names (in the above example "client1", "client2", and "client3") or the number of clients that can come back.

So in my code I have the following C# file

public class result
{

        public string name { get; set; }

        [JsonProperty("clients")]
        public string[] clients { get; set; }
}

However when I try to parse this using JsonConvert.DeserializeObject I get an error. Ideally what I would like to do is to convert the clients into a C# array and then iterate though them.

tmp dev
  • 8,043
  • 16
  • 53
  • 108
  • Your JSON example is not valid JSON. I understand you are trying to illustrate a concept, but to help you parse the actual string we need to see an actual string in the format that you have to work with. Can you mock up the elements in the JSON example so that they are properly representative? – John Wu Feb 27 '19 at 00:38
  • Thanks I have udpated with a valid JSON. Please note, I do not need to iterate through the attributes of each client, I just need to get the client names itself, as in the above example "client1", "client2", and "client3" – tmp dev Feb 27 '19 at 00:57

4 Answers4

0

You need to use Newtonsoft.JSON package.

        var respStr = @"{
                        name:'test',
                        clients: {
                            'client1': 'Bill',
                            'client2': 'Steve',
                            'client3': 'Ryan'
                            }
                        }";
        var jsonObject = JObject.Parse(respStr);
        foreach (var item in jsonObject)
        {
            var name = item.Key;
            JToken token = item.Value;
            if (token is JObject)
            {
                foreach (var clientToken in token)
                {
                    if (clientToken is JProperty)
                    {
                        var clientStr = (clientToken as JProperty).Value;
                    }
                }
            }
            if (token is JValue)
            {
                var value = token.Value<string>();
            }
        }
ozanmut
  • 2,898
  • 26
  • 22
0

You might declare the client as object array in order to achieve that.

public class result
{

    public string name { get; set; }

    [JsonProperty("clients")]
    public object[] clients { get; set; }
 }

In order to get clients name, you may loop through the object array property name. You might refer link below to achieve that.

Get properties and values from unknown object

skyxanxus
  • 81
  • 7
0

I would use...

public class result
{

    public string name { get; set; }

    [JsonProperty("clients")]
    public Dictionary<string, dynamic> Clients { get; set; }
}

With the code...

result test = JsonConvert.DeserializeObject<result>(Resource1.JSON);

Console.WriteLine(test.Clients["client1"].id);
Console.WriteLine(test.Clients["client2"].name);
Console.ReadLine();

Outputs...

1 
testName

Alternatively if you're unsure of the properties you can tweak this as follows

public class result
{

    public string name { get; set; }

    [JsonProperty("clients")]
    public Dictionary<string, ExpandoObject> Clients { get; set; }
}

With the code...

result  test = JsonConvert.DeserializeObject<result>(Resource1.JSON);

foreach(string key in test.Clients.Keys)
{
    ExpandoObject obj = test.Clients[key];
    var dict = obj as IDictionary<string, object>;
    dynamic client = obj;
    if (dict.ContainsKey("id"))
        Console.WriteLine(client.id);

    if (dict.ContainsKey("name"))
        Console.WriteLine(client.name);
}

To produce the same output

Mick
  • 6,527
  • 4
  • 52
  • 67
  • Thank you everyone for all your comments. Almost all of them worked, I decided to go ahead with using the ExpandoObject. – tmp dev Feb 27 '19 at 21:56
0

Looks like the list of clients is actually a keyed collection, a.k.a. a dictionary. So you'd represent it like this:

public class Foo
{
    public string name;
    public Dictionary<string, object> clients;
}

And deserialize and iterate as follows:

var input = @"{""name"":""test"",""clients"": {""client1"": {""id"": ""1"", ""count"": ""41""},""client2"": {""name"": ""testName""},""client3"": {""CustomerID"": ""a1"", ""internalID"": ""testID""}}}";
var foo = JsonConvert.DeserializeObject<Foo>(input);
foreach (var item in foo.clients)
{
    Console.WriteLine(item.Key);
}

Output:

client1
client2
client3

Example on DotNetFiddle

John Wu
  • 50,556
  • 8
  • 44
  • 80