PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, July 24, 2022

[FIXED] How to traverse dynamic nested json in c# recursively

 July 24, 2022     .net, asp.net, asp.net-core, c#, json     No comments   

Issue

If dataGeneratorType is range then the value can be anything between dataGeneratorStart and dataGeneratorEnd. If dataGeneratorType is array with no length property then the value will be one value randomly selected from the array, otherwise it be two randomly selected values that equals to the length. If it is the object (which can be more nested) then it will again follow the above logic. But this is where it gets tricky for me. Is there any dynamic way to solve the problem in C#.

Input payload json

{
    "temperature": {
        "type": "int",
        "dataGeneratorType": "range",
        "dataGeneratorStart": -5,
        "dataGeneratorEnd": 55
    },
    "salesAmount": {
        "type": "float",
        "dataGeneratorType": "array",
        "dataGeneratorArray": [
            0.51,
            13.33,
            20.01,
            1.54
        ]
    },
    "city": {
        "type": "string",
        "dataGeneratorType": "array",
        "dataGeneratorArray": [
            "UK",
            "Iceland",
            "Portugal",
            "Spain"
        ]
    },
    "relatedTags": {
        "type": "array",
        "dataGeneratorType": "array",
        "dataGeneratorArray": [
            "Sport",
            "Hardware",
            "Cycling",
            "Magazines"
        ],
        "length": 2
    },
    "salesDetail": {
        "type": "object",
        "dataGeneratorType": "object",
        "dataGeneratorValue": {
            "VAT": {
                "type": "float",
                "dataGeneratorType": "range",
                "dataGeneratorStart": 0.0,
                "dataGeneratorEnd": 20.0
            },
            "discountAmount": {
                "type": "float",
                "dataGeneratorType": "array",
                "dataGeneratorArray": [
                    0.10,
                    0.15,
                    0.20
                ]
            }
        }
    }
}

To output json:

{
    "temperature": 20,
    "salesAmount": 20.01,
    "city": "Iceland",
    "relatedTags": [
        "Sport",
        "Cycling"
    ],
    "salesDetails": {
        "VAT": 15.0,
        "discount": 0.1
    }
}

Solution

Please try this:

static string TransformJson(string inputPayload)
{
    JObject obj = JObject.Parse(inputPayload);
    var manipulatedObj = obj.DeepClone();
    foreach (var child in obj)
    {
        var key = child.Key;
        var t = child.Value["type"];
        JToken genType;
        if (!((JObject)child.Value).TryGetValue("dataGeneratorType", out genType))
        {
            continue; // genType is not found so, continue with next object.
        }

        var str = genType.Type == JTokenType.String ? genType.ToString().ToLower() : null;
        switch (str)
        {
            case "range":
                var r = new Random();
                if (((string)t).ToLower() == "float")
                {
                    var s = (float)child.Value["dataGeneratorStart"];
                    var e = (float)child.Value["dataGeneratorEnd"];
                    manipulatedObj[key] = r.NextDouble() * e;
                }
                else
                {
                    var s = (int)child.Value["dataGeneratorStart"];
                    var e = (int)child.Value["dataGeneratorEnd"];
                    manipulatedObj[key] = r.Next(s, e);
                }

                break;
            case "array":
                var arr = child.Value["dataGeneratorArray"];
                JToken lengthToken;
                if (!((JObject)child.Value).TryGetValue("length", out lengthToken))
                {
                    lengthToken = 2.ToString();
                }

                if ((string)t != "array")
                {
                    manipulatedObj[key] = arr.OrderBy(a => a).LastOrDefault();
                }
                else
                {
                    var count = arr.Count() >= (int)lengthToken ? (int)lengthToken : arr.Count();
                    var item = new JArray();
                    foreach (var m in Enumerable.Range(0, count).Select(i => arr[i]))
                    {
                        item.Add(m);
                    }

                    manipulatedObj[key] = item;
                }

                break;
            case "object":
                var transformJson = TransformJson(child.Value["dataGeneratorValue"].ToString());
                manipulatedObj[key] = JObject.Parse(transformJson);
                break;
            default:
                manipulatedObj[key] = child.Value["dataGeneratorValue"];
                break;
        }
    }

    return manipulatedObj.ToString(Formatting.Indented);
}

And use it as below:

var serializeObject =   @"{""temperature"":{""type"":""int"",""dataGeneratorType"":""range"",""dataGeneratorStart"":-5,""dataGeneratorEnd"":55},""salesAmount"":{""type"":""float"",""dataGeneratorType"":""array"",""dataGeneratorArray"":[0.51,13.33,20.01,1.54]},""relatedTags"":{""type"":""array"",""dataGeneratorType"":""array"",""dataGeneratorArray"":[""Sport"",""Hardware"",""Cycling"",""Magazines""],""length"":2},""salesDetail"":{""type"":""object"",""dataGeneratorType"":""object"",""dataGeneratorValue"":{""VAT"":{""type"":""float"",""dataGeneratorType"":""range"",""dataGeneratorStart"":0.0,""dataGeneratorEnd"":20.0},""discountAmount"":{""type"":""float"",""dataGeneratorType"":""array"",""dataGeneratorArray"":[0.1,0.15,0.2]}}}}";
Console.WriteLine(serializeObject);
var outputJson = TransformJson(serializeObject);
Console.WriteLine(System.Environment.NewLine + "Modified Json = " + System.Environment.NewLine);
Console.WriteLine(outputJson);

I just added everything in one function but you can split into multiple functions and/or classes to make unit testing easier.

Here is the dotnet fiddle.



Answered By - sam
Answer Checked By - Willingham (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing