我有一个追随者JSON。我添加了 2 x双引号, 以便可以string在c#中将其声明为变量,实际上,它包含属性的双引号的一倍。完整的示例代码在这个小提琴中。
JSON
string
c#
我正在使用,Newtonsoft但也可以使用System.Text.Json,因此对于任何一种工作解决方案都将不胜感激。
Newtonsoft
System.Text.Json
{ ""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 } ] }
如果我的密钥JSON与列表中的项目匹配,我想添加验证及其子密钥。我有三种情况,下面的代码按注释对它们进行了解释。
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(); }
该JSON迭代函数显示如下。
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 } } }
我的决赛JSON应该如下图所示。
{ ""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 } ] }
我无法实现所有三种情况。有人可以看看并提供解决方案吗?另外,如果有更好的方法可以解决此问题,请提供该方法的解决方案。
我制造了一个小提琴,以轻松地帮助我。
我设法解决了这个问题,在这里发布了一个解决方案,以防它可以帮助其他人。我已经意识到json中的所有控件都是组件对象/数组的一部分,因此我们可以使用JSONPath,请参阅链接以获取更多详细信息。以下代码可以解决问题:
JSONPath
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 } } } } }