Click here to Skip to main content
15,885,182 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Currently I have a JsonFieldsCollector that checks the Json response if its an Array, Object/ object Property and store them in dictionary and print them. but I have one Json like the one below returned from the server

[
   {
    id:1
    name: "John"
   },
   {
    id:2
    name: "Bob"
   }
]


Currently it prints like this
[0].id: 1
[0].name : john
[1].id : 2
[2].name : Bob

I want to print with out the the index []. like
id: 1
name: john

//Here is the JsonFieldsCollector class
public class JsonFieldsCollector
  {
      private readonly Dictionary<string, JValue> fields;

      public JsonFieldsCollector(JToken token)
      {
          fields = new Dictionary<string, JValue>();
          CollectFields(token);
      }

      private void CollectFields(JToken jToken)
      {
          switch (jToken.Type)
          {
              case JTokenType.Object:
                  foreach (var child in jToken.Children<JProperty>())
                      CollectFields(child);
                  break;
              case JTokenType.Array:
                  foreach (var child in jToken.Children())
                      CollectFields(child);
                  break;
              case JTokenType.Property:
                  CollectFields(((JProperty)jToken).Value);
                  break;
              default:
                  fields.Add(jToken.Path, (JValue)jToken); //here is where it adding from indexes"[0].id"
                  break;
          }
      }

      public IEnumerable<KeyValuePair<string, JValue>> GetAllFields() => fields;



      public static void Usage(IRestResponse response)
      {
          var Json = JToken.Parse(response.Content);
          var fieldsCollector = new JsonFieldsCollector(Json);
          var fields = fieldsCollector.GetAllFields();
          foreach (var field in fields)
          {
              Console.WriteLine($"{field.Key}: {field.Value}");
          }

      }


What I have tried:

Not sure I can accomplish this.. please any help would be great
Posted
Updated 25-Jun-20 14:10pm
v2

1 solution

Well, not necessarily the proper way of solving it, but
default:
  fields.Add(jToken.Path, (JValue)jToken); //here is where it adding from indexes"[0].id"
  break;

could be

default:
  // Needs a using System.Linq; 
  String pathLast = jToken.Path.Split('.').Last();
  String tokenLast = (JValue)jToken.Split('.').Last();

  fields.Add(pathLast, tokenLast); 
  break;


[Edit] - will this work ?
foreach (var field in fields)
{
  String keyLastSegment = field.Key.ToString().Split('.').Last();
  Console.WriteLine($"{keyLastSegment}: {field.Value}");
}
[/Edit]


Obviously if you deserialised the JSON to a List<simple poco> containing the two string fields eg tag, name you'd get the result as well, and wouldnt need to use this fields collector mechanism - since I dont know what else you may be doing with the JSON, it might not be a suitable method
 
Share this answer
 
v4
Comments
Member 14779968 25-Jun-20 20:10pm    
Hi Garth thanks for your response. String tokenLast = (JValue)jToken.Split('.').Last(); its giving an error saying no Split method is defined for Jtoken.

Also My main reason for the fields collector mechanism is get all the property and value from the server after hitting the API and then I want to validate a Model C# object class to it and check if the property and its value matches/contains the same as the Model.

Also Some of the API response have Array and objects or a mix.. thats why I thought maybe adding a If condition would the trick

I did something like this.. but my if condition is hard coded to check only "[0]." and I am getting many indexes
if(jToken.Path.Contains("[0]."))
{
var output = RemoveBracketsandNumber(jToken.Path);
fields.Add(output, (JValue)jToken);
}
else
fields.Add(jToken.Path, (JValue)jToken); //here is where it adding from indexes"[0].id"
break;
public static string RemoveBracketsandNumber(string str)
{
str = Regex.Replace(str, @"\[.+?\]", "");
str = str.Replace(".", "");
return str;
}
Garth J Lancaster 25-Jun-20 20:35pm    
I was having a coffee and had an oh-no moment - you're going to a dictionary so that's not the correct place to do that conversion anyway .. I'm going to modify the response

See the edit I did - at the output stage - hopefully there's a ToString() exposed on that object
Member 14779968 25-Jun-20 20:45pm    
yup that did the trick Thank you :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900