-2

I have read many SO posts on this subject, but either they don't deal with this level of nesting, or their answers simply haven't worked. Thank you in advance for any guidance.

I'm calling a web API that's returning a Json object, I have used the https://json2csharp.com to convert that Json to a C# class.

That all works fine, but im struggling to now convert the object to just a list of ChildComponents, meaning every childComponent in the JSON, regardless of which ChildFolder it might be in.

So at the end I just want one list, containing hundreds of ChildComponents.

public class ChildComponent
{
public int id { get; set; }
public string name { get; set; }
public string state { get; set; }
public string type { get; set; }
public string uuid { get; set; }
public List<ChildComponent> childComponents { get; set; }
public int? inboundQueueSize { get; set; }
public int? outboundQueueSize { get; set; }
public int? failedQueueSize { get; set; }
}

public class ChildFolder
{
public int id { get; set; }
public string name { get; set; }
public List<ChildFolder> childFolders { get; set; }
public List<ChildComponent> childComponents { get; set; }
public string uuid { get; set; }
}

public class Data
{
public int id { get; set; }
public string name { get; set; }
public List<ChildFolder> childFolders { get; set; }
public List<object> childComponents { get; set; }
public string uuid { get; set; }
}

public class Root
{
public Data data { get; set; }
public object error { get; set; }
}

That is the C# class, notice they can have lists of folders and components at pretty much any level.

So how can I parse all that to end up with a single list?

Currently have the json to C# in an object named js.

 var response = await HttpClient.GetAsync($"{BaseUrl}api/components/status");
        var content = await response.Content.ReadAsStringAsync();
        var js = JsonConvert.DeserializeObject<Root>(content);

I have tried walking through js with foreach loops, but am concerned I might not be checking all the folders for components.

var folder = js.data.childFolders;
        
        while (folder.Count > 0)
        {
            foreach (var childFolder in folder)
            {

                if (childFolder.childComponents.Count > 0)
                {
                    foreach (var childFolderChildComponent in childFolder.childComponents)
                    {
                        Enum.TryParse<ComponentState>(childFolderChildComponent.state, out var  state);
                        Enum.TryParse<ComponentType>(childFolderChildComponent.type, out var type);
                        
                        var currentComponent = new ComponentModel
                        {
                            Id = childFolderChildComponent.id,
                            Name = childFolderChildComponent.name,
                            UUID = childFolderChildComponent.uuid,
                            State = state,
                            Type = type
                            
                        };

                        dictComponents.TryAdd(currentComponent.Id, currentComponent);
                    }

                }
                
            }

           
        }
Talcon
  • 1
  • 1
  • You already deserialized the JSON file into your own classes the weirdly named `js` variable. What's the actual question? This has nothing to do with JSON any more. You already have the nested lists you asked for – Panagiotis Kanavos Feb 23 '23 at 16:46
  • Can you post an example of your json pls. It is not clear at all what you are talking about. – Serge Feb 23 '23 at 16:51
  • I now need to go from nested lists to 1 list that holds all entries from any ChildComponent list at any ChildFolder level. – Talcon Feb 23 '23 at 16:51
  • Is the real question how to recursively search a tree of items? This has nothing to do with JSON. There are a *lot* of answers for the actual problem already. Check [this one](https://stackoverflow.com/questions/56001282/linq-recursive-search-nodes) for example. You need to use recursion to walk the tree and return the items you want – Panagiotis Kanavos Feb 23 '23 at 16:52

1 Answers1

-1

Thank you to all who commented.

This method was able to extract what I needed.

public class ComponentFinder
{
    public List<ChildComponent> FindComponents(Root root)
     {
    var components = new List<ChildComponent>();

    // Recursively search for components in child folders
    foreach (var folder in root.data.childFolders)
    {
        components.AddRange(FindComponentsInFolder(folder));
    }

       return components;
      }

private List<ChildComponent> FindComponentsInFolder(ChildFolder folder)
{
    var components = new List<ChildComponent>();

    // Check if the folder contains any components
    if (folder.childComponents != null)
    {
        components.AddRange(folder.childComponents);
    }

    // Recursively search for components in child folders
    if (folder.childFolders != null)
    {
        foreach (var childFolder in folder.childFolders)
        {
            components.AddRange(FindComponentsInFolder(childFolder));
        }
    }

    return components;
    }
}
Talcon
  • 1
  • 1
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 28 '23 at 02:08