0

Is there a JsonElement and JsonValueKind equivalent in newtonsoft Json? What would be the correct code to port the below code that uses System.Text.Json to newtonsoft Json? Reason for my port in due to my dll not able to find the right System.Buffers assembly version. I followed all the advices I could get but still I am unable to resolve it. So thought of using Newtonsoft Json.

public static Dictionary<string, dynamic> JsonDeserialize(string Json)
    {
        JsonElement elm = JsonSerializer.Deserialize<JsonElement>(Json);
        Dictionary<string, dynamic> dict = ElementToDict(elm);
        return dict;
    }


public static dynamic ElementToDict(JsonElement obj)
{
    if (obj.ValueKind == JsonValueKind.Number)
    {
        return StringToDecimal(obj.GetRawText());
    }
    else if (obj.ValueKind == JsonValueKind.String)
    {
        return obj.GetString();
    }
    else if (obj.ValueKind == JsonValueKind.True || obj.ValueKind == JsonValueKind.False)
    {
        return obj.GetBoolean();
    }
    else if (obj.ValueKind == JsonValueKind.Object)
    {
        var map = obj.EnumerateObject().ToList();
        var newMap = new Dictionary<String, dynamic>();
        for (int i = 0; i < map.Count; i++)
        {
            newMap.Add(map[i].Name, ElementToDict(map[i].Value));
        }
        return newMap;
    }
    else if (obj.ValueKind == JsonValueKind.Array)
    {
        var items = obj.EnumerateArray().ToList();
        var newItems = new ArrayList();
        for (int i = 0; i < items.Count; i++)
        {
            newItems.Add(ElementToDict(obj[i]));
        }
        return newItems;
    }
    else
    {
        return null;
    }
}

2 Answers2

0

You can try using JToken and JTokenType:

var tok = JsonConvert.DeserializeObject<JToken>("{\"test\": 1}"); // or JToken.Parse
Console.WriteLine(tok.Type); // prints "Object"
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • hi, I am facing trouble in converting to newtonsoft for this part... can you help? else if (obj.ValueKind == JsonValueKind.Object) { var map = obj.EnumerateObject().ToList(); var newMap = new Dictionary(); for (int i = 0; i < map.Count; i++) { newMap.Add(map[i].Name, ElementToDict(map[i].Value)); } return newMap; } – Ansar Bedharudeen Sep 02 '20 at 19:01
  • @AnsarBedharudeen try looking into [LINQ to JSON](https://www.newtonsoft.com/json/help/html/LINQtoJSON.htm) – Guru Stron Sep 02 '20 at 19:18
  • thanks for your advice. I went through the doc. What I fail to acheive is a "recursive deserialiser". The function ElementToDict(JsonElement obj) acheive this through recursive calls. I am unable to find a way to implement obj.EnumerateArray().ToList() and map[i].Name in Newtonsoft Json. Please advice. – Ansar Bedharudeen Sep 03 '20 at 07:21
  • @AnsarBedharudeen `obj.Children().ToList()`? or [this answer](https://stackoverflow.com/a/63487391/2501279) – Guru Stron Sep 03 '20 at 08:51
0

Thanks to @guru-stron I sucessfully ported to Newtonsoft.Json. Following is my code:

public static Dictionary<string, dynamic> JsonDeserialize(string Json)
        {
            Console.WriteLine(Json);
            var elm = JsonConvert.DeserializeObject<JToken>(Json);
            // Replace double with decimal in the map
            Dictionary<string, dynamic> dict = ElementToDict(elm);
            return dict;
        }


public static dynamic ElementToDict(JToken obj)
        {
            
            if (obj.Type == JTokenType.Float || obj.Type == JTokenType.Integer)
            {
                return StringToDecimal(obj.ToString());
            }
            else if (obj.Type == JTokenType.String)
            {
                return obj.ToString();
            }
            else if (obj.Type == JTokenType.Boolean)
            {
                return obj.ToObject<Boolean>();
            }
            else if (obj.Type == JTokenType.Object)
            {
                var map = obj.Children().ToList();
                var newMap = new Dictionary<String, dynamic>();
                foreach (JProperty m in map)
                {
                    newMap.Add(m.Name, ElementToDict(m.Value));
                }
                return newMap;
            }
            else if (obj.Type == JTokenType.Array)
            {
                var items = obj.AsJEnumerable().ToList();
                var newItems = new ArrayList();
                for (int i = 0; i < items.Count; i++)
                {
                    newItems.Add(ElementToDict(obj[i]));
                }
                return newItems;
            }
            else
            {
                return null;
            }
        }