Adding a property into specified location into json using Newtonsoft.Json

拜拜、爱过 提交于 2020-06-07 07:24:29

问题


I have a following JSON. I have added 2 x double quotes so that I could declare it as stringvariable in c#, in reality it contains one times double quotes for properties. The complete example code is in this fiddle.

I am using Newtonsoft but can use System.Text.Json as well so a working solution for either will be appreciated.

{
  ""display"": ""wizard"",
  ""settings"": {},
  ""components"": [
    {
      ""title"": ""Activity Information"",
      ""label"": ""Activity Information"",
      ""type"": ""Activity"",
      ""key"": ""ActivityInformation"",
      ""components"": [
        {
          ""label"": ""Row1Columns"",
          ""columns"": [
            {
              ""components"": [
                {
                  ""label"": ""Activity Date"",
                  ""format"": ""dd/MM/yyyy hh:mm a"",
                  ""tableView"": false,
                  ""datePicker"": {
                    ""disableWeekends"": false,
                    ""disableWeekdays"": false
                  },
                  ""validate"": {
                    ""unique"": true
                  },
                  ""key"": ""Activity.ActivityDate"",
                  ""type"": ""datetime"",
                  ""input"": true,
                  ""suffix"": ""<i ref=\""icon\"" class=\""fa fa-calendar\"" style=\""\""></i>"",
                  ""widget"": {
                    ""type"": ""calendar"",
                    ""displayInTimezone"": ""viewer"",
                    ""language"": ""en"",
                    ""useLocaleSettings"": false,
                    ""allowInput"": true,
                    ""mode"": ""single"",
                    ""enableTime"": true,
                    ""noCalendar"": false,
                    ""format"": ""dd/MM/yyyy hh:mm a"",
                    ""hourIncrement"": 1,
                    ""minuteIncrement"": 1,
                    ""time_24hr"": false,
                    ""minDate"": null,
                    ""disableWeekends"": false,
                    ""disableWeekdays"": false,
                    ""maxDate"": null
                  }
                }
              ],
              ""width"": 6,
              ""offset"": 0,
              ""push"": 0,
              ""pull"": 0
            },
            {
              ""components"": [
                {
                  ""label"": ""Duration (minutes)"",
                  ""mask"": false,
                  ""spellcheck"": true,
                  ""tableView"": false,
                  ""delimiter"": false,
                  ""requireDecimal"": false,
                  ""inputFormat"": ""plain"",
                  ""key"": ""Activity.Duration"",
                  ""type"": ""number"",
                  ""input"": true
                }
              ],
              ""width"": 6,
              ""offset"": 0,
              ""push"": 0,
              ""pull"": 0
            }
          ],
          ""tableView"": false,
          ""key"": ""row1Columns"",
          ""type"": ""columns"",
          ""input"": false
        },
        {
          ""label"": ""Row2Columns"",
          ""columns"": [
            {
              ""components"": [
                {
                  ""label"": ""Activity Category"",
                  ""widget"": ""choicesjs"",
                  ""tableView"": true,
                  ""dataSrc"": ""custom"",
                  ""data"": {
                    ""custom"": ""values = getActivityCategoryValues()""
                  },
                  ""valueProperty"": ""AgencyActivityCategoryId"",
                  ""template"": ""<span>{{ item.text }}</span>"",
                  ""selectThreshold"": 0.3,
                  ""validate"": {
                    ""required"": true
                  },
                  ""key"": ""Activity.AgencyActivityCategoryId"",
                  ""type"": ""select"",
                  ""indexeddb"": {
                    ""filter"": {}
                  },
                  ""input"": true
                }
              ],
              ""width"": 6,
              ""offset"": 0,
              ""push"": 0,
              ""pull"": 0
            },
            {
              ""components"": [
                {
                  ""label"": ""Attendance"",
                  ""widget"": ""choicesjs"",
                  ""tableView"": true,
                  ""multiple"": false,
                  ""dataSrc"": ""custom"",
                  ""data"": {
                    ""custom"": ""values = getAttendanceValues()""
                  },
                  ""valueProperty"": ""AgencyActivityAttendanceId"",
                  ""template"": ""<span>{{ item.text }}</span>"",
                  ""selectThreshold"": 0.3,                  
                  ""key"": ""Activity.AgencyActivityAttendanceId"",
                  ""type"": ""select"",
                  ""indexeddb"": {
                    ""filter"": {}
                  },
                  ""input"": true
                }
              ],
              ""width"": 6,
              ""offset"": 0,
              ""push"": 0,
              ""pull"": 0
            }
          ],
          ""tableView"": false,
          ""key"": ""row2Columns"",
          ""type"": ""columns"",
          ""input"": false
        },
        {
          ""label"": ""Activity Options"",
          ""widget"": ""choicesjs"",
          ""tableView"": true,
          ""multiple"": true,
          ""dataSrc"": ""custom"",
          ""data"": {
            ""custom"": ""values = getActivityManagerValues(data.Activity.AgencyActivityCategoryId)""
          },
          ""template"": ""<span>{{ item.text }}</span>"",
          ""refreshOn"": ""Activity.AgencyActivityCategoryId"",
          ""clearOnRefresh"": true,
          ""selectThreshold"": 0.3,
          ""calculateServer"": false,
          ""validate"": {
            ""required"": true,
            ""multiple"": true
          },
          ""key"": ""Activity.ActivityDetail"",
          ""type"": ""select"",
          ""indexeddb"": {
            ""filter"": {}
          },
          ""input"": true
        }
    ],
      ""input"": false,
      ""tableView"": false,
      ""breadcrumbClickable"": true,
      ""buttonSettings"": {
        ""previous"": true,
        ""cancel"": true,
        ""next"": true
      },
      ""collapsible"": false
    }
  ]
}

I want to add validate and it's child key required, if key of my JSON matches with an item in my list. I have three scenarios and they are explained as per comments in the code below.

public static void Main()
    {
        Console.WriteLine("BEFORE MANDATORY");
        List<string> mandatoryKeys = new List<string>();
//Scenario 1: Has validate key but not required key in json, so we need to add "required": true 
//inside existing "validate"
        mandatoryKeys.Add("Activity.ActivityDate");
//Scenario 2: Does not have both validate and required so will need to have both "validate" and its child "required"
        mandatoryKeys.Add("Activity.Duration");
//Scenario 3: Has both "validate" and "required" so we should not add it again
        mandatoryKeys.Add("Activity.AgencyActivityCategoryId");
//Scenario 2 again for double checking
        mandatoryKeys.Add("Activity.AgencyActivityAttendanceId");

        var data = JObject.Parse(GetRawJson());
        Console.WriteLine(data);
        for(int i = 0; i < mandatoryKeys.Count(); i++)
            IterateJson(data, mandatoryKeys[i]);

        Console.WriteLine("AFTER MANDATORY");
        Console.WriteLine("XXXXXXXXXXXXXXX");
        Console.WriteLine(data);
        Console.ReadLine();
    }

The JSON iteration function is displayed below.

static void IterateJson(JToken value, string mandatoryFieldKey)
    {
//if more than 0 - so value is object or array and we have to call this method for each property
        if (value.Values().Count() != 0) 
        {
            foreach (var item in value.Values().ToList())
            {
                IterateJson(item, mandatoryFieldKey);
            }
        }
        else if (value.ToString() == mandatoryFieldKey)
        {
            Console.WriteLine("HELLO");
 //check if above "required" property exists 
            if (value.Parent.Parent is JObject jObject && jObject["validate"] == null)
            {
                Console.WriteLine(value);
                jObject.Add("validate", JObject.FromObject(new { required = true })); //add required property
            }
        }

    }

My final JSON should look like as shown below.


{
  ""display"": ""wizard"",
  ""settings"": {},
  ""components"": [
    {
      ""title"": ""Activity Information"",
      ""label"": ""Event Information"",
      ""type"": ""Activity"",
      ""key"": ""ActivityInformation"",
      ""components"": [
        {
          ""label"": ""Row1Columns"",
          ""columns"": [
            {
              ""components"": [
                {
                  ""label"": ""Activity Date"",
                  ""format"": ""dd/MM/yyyy hh:mm a"",
                  ""tableView"": false,
                  ""datePicker"": {
                    ""disableWeekends"": false,
                    ""disableWeekdays"": false
                  },
                  ""validate"": {
                    ""required"": true,
                    ""unique"": true
                  },
                  ""key"": ""Activity.ActivityDate"",
                  ""type"": ""datetime"",
                  ""input"": true,
                  ""suffix"": ""<i ref=\""icon\"" class=\""fa fa-calendar\"" style=\""\""></i>"",
                  ""widget"": {
                    ""type"": ""calendar"",
                    ""displayInTimezone"": ""viewer"",
                    ""language"": ""en"",
                    ""useLocaleSettings"": false,
                    ""allowInput"": true,
                    ""mode"": ""single"",
                    ""enableTime"": true,
                    ""noCalendar"": false,
                    ""format"": ""dd/MM/yyyy hh:mm a"",
                    ""hourIncrement"": 1,
                    ""minuteIncrement"": 1,
                    ""time_24hr"": false,
                    ""minDate"": null,
                    ""disableWeekends"": false,
                    ""disableWeekdays"": false,
                    ""maxDate"": null
                  }
                }
              ],
              ""width"": 6,
              ""offset"": 0,
              ""push"": 0,
              ""pull"": 0
            },
            {
              ""components"": [
                {
                  ""label"": ""Duration (minutes)"",
                  ""mask"": false,
                  ""spellcheck"": true,
                  ""tableView"": false,
                  ""delimiter"": false,
                  ""requireDecimal"": false,
                  ""inputFormat"": ""plain"",
                  ""validate"": {
                    ""required"": true                    
                  },
                  ""key"": ""Activity.Duration"",
                  ""type"": ""number"",
                  ""input"": true
                }
              ],
              ""width"": 6,
              ""offset"": 0,
              ""push"": 0,
              ""pull"": 0
            }
          ],
          ""tableView"": false,
          ""key"": ""row1Columns"",
          ""type"": ""columns"",
          ""input"": false
        },
        {
          ""label"": ""Row2Columns"",
          ""columns"": [
            {
              ""components"": [
                {
                  ""label"": ""Activity Category"",
                  ""widget"": ""choicesjs"",
                  ""tableView"": true,
                  ""dataSrc"": ""custom"",
                  ""data"": {
                    ""custom"": ""values = getActivityCategoryValues()""
                  },
                  ""valueProperty"": ""AgencyActivityCategoryId"",
                  ""template"": ""<span>{{ item.text }}</span>"",
                  ""selectThreshold"": 0.3,
                  ""validate"": {
                    ""required"": true
                  },
                  ""key"": ""Activity.AgencyActivityCategoryId"",
                  ""type"": ""select"",
                  ""indexeddb"": {
                    ""filter"": {}
                  },
                  ""input"": true
                }
              ],
              ""width"": 6,
              ""offset"": 0,
              ""push"": 0,
              ""pull"": 0
            },
            {
              ""components"": [
                {
                  ""label"": ""Attendance"",
                  ""widget"": ""choicesjs"",
                  ""tableView"": true,
                  ""multiple"": false,
                  ""dataSrc"": ""custom"",
                  ""data"": {
                    ""custom"": ""values = getAttendanceValues()""
                  },
                  ""valueProperty"": ""AgencyActivityAttendanceId"",
                  ""template"": ""<span>{{ item.text }}</span>"",
                  ""selectThreshold"": 0.3,     
                  ""validate"": {
                    ""required"": true
                  },
                  ""key"": ""Activity.AgencyActivityAttendanceId"",
                  ""type"": ""select"",
                  ""indexeddb"": {
                    ""filter"": {}
                  },
                  ""input"": true
                }
              ],
              ""width"": 6,
              ""offset"": 0,
              ""push"": 0,
              ""pull"": 0
            }
          ],
          ""tableView"": false,
          ""key"": ""row2Columns"",
          ""type"": ""columns"",
          ""input"": false
        },
        {
          ""label"": ""Activity Options"",
          ""widget"": ""choicesjs"",
          ""tableView"": true,
          ""multiple"": true,
          ""dataSrc"": ""custom"",
          ""data"": {
            ""custom"": ""values = getActivityManagerValues(data.Activity.AgencyActivityCategoryId)""
          },
          ""template"": ""<span>{{ item.text }}</span>"",
          ""refreshOn"": ""Activity.AgencyActivityCategoryId"",
          ""clearOnRefresh"": true,
          ""selectThreshold"": 0.3,
          ""calculateServer"": false,
          ""validate"": {
            ""required"": true,
            ""multiple"": true
          },
          ""key"": ""Activity.ActivityDetail"",
          ""type"": ""select"",
          ""indexeddb"": {
            ""filter"": {}
          },
          ""input"": true
        }
    ],
      ""input"": false,
      ""tableView"": false,
      ""breadcrumbClickable"": true,
      ""buttonSettings"": {
        ""previous"": true,
        ""cancel"": true,
        ""next"": true
      },
      ""collapsible"": false
    }
  ]
}

I am unable to implement all three scenarios. Can someone have a look and provide a solutions? Also, if there is a better approach for accomplishing this then please provide a solution for that approach.

I have created a fiddle to make it easy to help me.


回答1:


I have managed to fix this issue, posting a solution here in case it can help others. I have realised that all controls in my json are part of component object/array so we can use JSONPath, see the link for more details. Following code has done the trick:

public void IterateJson(JObject obj, string mandatoryFieldKey)
        {
JToken jTokenFoundForMandatoryField = obj.SelectToken
("$..components[?(@.key == '" + mandatoryFieldKey + "')]");   
            //Now we convert this oken into an object so that we can add properties/objects in it
            if (jTokenFoundForMandatoryField is JObject jObjectForMandatoryField)
            {
                //We check if validate already exists for this field, if it does not
 //exists then we add validate and required property inside the if condition
                if (jObjectForMandatoryField["validate"] == null)
                    jObjectForMandatoryField.Add("validate", 
JObject.FromObject(new { required = true })); //add validate and required property
                else
                {
                    //If validate does not exists then code comes here and 
//we convert the validate into a JObject using is JObject statement
                    if (jObjectForMandatoryField["validate"] is JObject validateObject)
                    {
                        //We need to check if required property already exists, 
//if it does not exists then we add it inside the if condition.
                        if (validateObject["required"] == null)
                        {
                            validateObject.Add("required", true); //add required property
                        }
                    }
                }                
            }     
}


来源:https://stackoverflow.com/questions/62140014/adding-a-property-into-specified-location-into-json-using-newtonsoft-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!