Search code examples
c#jsonjavascriptserializer

How to work with dynamic nested JSON document in C#


I have a nested dynamic JSON template document which i need to De-serialize it and insert values to it to make a JSON content which has values in it. I have a working logic for non nested JSON but I am not sure how to make the logic (Recursive or some other easier approach if any) which work with nested document.

Sample JSON template

{
"LoanDate": [
    "Test"
],
"borrowerdetail": [
    {
        "borrowid": [
            "Test"
        ],
        "Name": [
            "Test"
        ],
        "Type": [
            "Test"
        ],
        "Status": [
            "Test"
        ]
    }
],
"loans": [
    {
        "bibdetails": [
            {
                "id": [
                    "Test"
                ],
                "title": [
                    "Test"
                ],
                "author": [
                    "Test",
                    "Test"
                ]
            }
        ],
        "Collection": [
            "Test"
        ],
        "ItemType": [
            "Test"
        ],
        "ItemNo": [
            "Test"
        ]
    }
],
"LoansItemBib": [
    "Test"
],
"LoansItem": [
    "Test"
]
}

Current Logic

JavaScriptSerializer _objSolrDeserialized = new JavaScriptSerializer();
SolrResultTemp = "{";
dynamic SolrTempObject = _objSolrDeserialized.Deserialize<dynamic>(SolrResultTemp);
string Serialized = _objSolrDeserialized.Serialize(SolrTempObject);
int _iParentCount = 0;
foreach (var ObjSolr in SolrTempObject)
{
    var Type = ObjSolr.Value.GetType();
    if (Type.Name == "String")
    {
        string Value = ObjSolr.Value.Replace("$", "").Replace("^", "");
        List<string> ResString = ReturnConciseValEntry(Value, null, db2, FullTextPath, null, null);
        if (ResString.Count > 0)
        {
            foreach (var Res in ResString)
            {
                if (_iParentCount > 0)
                    SolrResultTemp = SolrResultTemp + ",";
                SolrResultTemp = SolrResultTemp + "\"" + ObjSolr.Key + "\": \"" + Res + "\"";
                _iParentCount += 1;
            }
        }
    }
    if (Type.Name == "Object[]")
    {
        string Key = ObjSolr.Key;
        List<string> _lstValue = new List<string>();
        foreach (var x in ObjSolr.Value)
        {
            string Value = x.Replace("$", "").Replace("^", "");
            List<string> ResString = ReturnConciseValEntry(Value, null, db2, FullTextPath, null, null);
            if (ResString.Count > 0)
                _lstValue.AddRange(ResString);
        }
        if (_lstValue.Count > 0)
        {
            if (_iParentCount > 0)
                SolrResultTemp = SolrResultTemp + ",";
            SolrResultTemp = SolrResultTemp + "\"" + ObjSolr.Key + "\" : [ \"" + string.Join("\" , \"", _lstValue) + "\" ]";
            _iParentCount += 1;
        }
    }
}
SolrResultTemp = SolrResultTemp + "}";

Solution

  • I had to use Recursive approach to get the job done. Here's the working code.

    Code

        public IDictionary<string, object> ProcessJson(IDictionary<string, object> inputDic, LoansLogData loandata, string itemno, string parentKey = "", string childKey = "", int cnt = 1)
        {
            dynamic flexible = new ExpandoObject();
    
            IDictionary<string, object> ResultDic = (IDictionary<string, object>)flexible;
            try
            {
    
                foreach (KeyValuePair<string, object> entry in inputDic)
                {
    
                    List<string> ElementCollection = new List<string>();
                    List<string> _lstValue = new List<string>();
                    if (entry.Value is System.Collections.ICollection)
                    {
                        var countProp = entry.Value.GetType().GetProperty("Count");
                        var count = (int)countProp.GetValue(entry.Value, null);
                        int loopcount = 0;
                        foreach (var item in (System.Collections.ICollection)entry.Value)
                        {
                            if (item is Dictionary<string, object>)
                            {
                                if (entry.Key != null && entry.Key.Trim().StartsWith("@"))
                                {
                                    parentKey = entry.Key.Trim();
                                    parentKey = parentKey.Substring(0, parentKey.IndexOf(' '));
                                    childKey = entry.Key.Trim().Replace(parentKey, "");
                                    childKey = childKey.Trim();
                                }
                                if (parentKey == "@Loans")
                                {
                                    List<IDictionary<string, object>> catList = new List<IDictionary<string, object>>();
                                    foreach (var singleBibItem in loandata.ItemNo)
                                    {
    
                                        catList.Add(ProcessJson((Dictionary<string, object>)item, loandata, singleBibItem, parentKey, childKey, cnt));
                                        cnt++;
                                    }
                                    ResultDic.Add(childKey, catList);
    
                                }
                                else
                                {
                                    List<IDictionary<string, object>> BorrowList = new List<IDictionary<string, object>>();
                                    BorrowList.Add(ProcessJson((Dictionary<string, object>)item, loandata, itemno, parentKey, childKey));
                                    ResultDic.Add(childKey, BorrowList);
                                }
                            }
                            else
                            {
    
                                List<string> ResString = ReturnLoanConciseValEntry(parentKey, (String)item, itemno, loandata, cnt);
                                if (ResString.Count > 0)
                                {
                                    _lstValue.AddRange(ResString);
                                }
                                if (_lstValue.Count > 0)
                                {
                                    if (((String)item == "LoansItemBib" || (String)item == "LoansItemNo"))
                                        _lstValue = _lstValue.Distinct().ToList();
                                    loopcount += 1;
                                    if (loopcount == count)
                                        ResultDic.Add(entry.Key, _lstValue);
                                }
    
                            }
    
                        }
                    }
    
                }
                return ResultDic;
            }
            catch (Exception ex)
            {
                return ResultDic;
            }
    
        }