I am getting a Json Array here is the JSON array
[
{
"customFieldName": "resolution",
"fieldName": "Resolution"
},
{
"customFieldName": "lastViewed",
"fieldName": "Last Viewed"
},
]
I want to convert the Keys to lower case please suggest the solution.
I tried to convert the JSON array to dictionary but not succeeded.
You can try reading all properties inside JsonArray and change the propertyname to lowercase
private static void ConvertToLowerCase(JArray jArray)
{
foreach (var item in jArray.Children())
{
foreach (var property in item.Children<JProperty>().ToList())
{
property.Replace(new JProperty(property.Name.ToLower(), property.Value));
}
}
}
call this method by passing the JArray
var jArray = JArray.Parse(jsonString);
ConvertToLowerCase(jArray);
Console.WriteLine(JsonConvert.SerializeObject(jArray));
Output
[{"customfieldname":"resolution","fieldname":"Resolution"},{"customfieldname":"lastViewed","fieldname":"Last Viewed"}]
Related
Given the following JSON
{
"enabled": true,
"name": "Name",
"description": "Test",
"rules": [
{
"propA": "a",
"propB": "b"
}
]
}
Is it possible in C# to deserialize on selected properties based on an input list:
var propertiesToInclude = new List<string> { "description", "rules.PropA" };
The example json is a simplified example, the real one can contain hundred of properties. The use case is to only return the fields that matches the input list in a dynamic or anonymous object and discard the other properties.
using Newtonsoft.Json.Linq;
var propertiesToInclude = new List<string> { "description", "rules.PropA" };
var splitted = propertiesToInclude.SelectMany(x => x.Split('.'));
string text = File.ReadAllText("test.json");
var json = JToken.Parse(text);
Process(json);
Console.WriteLine(json);
void Process(JToken token)
{
if (token is JObject jObject)
{
jObject.Properties()
.Where(x => !splitted.Contains(x.Name, StringComparer.OrdinalIgnoreCase))
.ToList()
.ForEach(x => x.Remove());
foreach (var x in jObject)
Process(x.Value);
}
else if (token is JArray jArray)
{
foreach (var x in jArray)
Process(x);
}
}
This code on the data shown will give the desired result.
The output is a JToken object containing the desired properties.
However, I used a simple search for all occurrences of names in a splited array. This will give false positives if, for example, the root object contains the propA property or the object in the array contains the description property.
To avoid this, you need to compare the JToken.Path property with the propertiesToInclude elements, taking into account the depth.
I have the following json
{
"audit_date": "2020-05-13T11:27:10.3187798Z",
"client_uuid": "2fd77dd8-ed76-4bba-b0e1-5cda454c8d6e",
"audit_entry": {
"where_uri": "test.com/dataservice/apps/171f0841-825b-4964-8f8c-0869650f14a6",
"why_uri": "test.com/dataservice/reference/reasons_for_change/61acc173-7168-4ae5-9f04- afa228941f8b",
"who_uri": "test.com/securityservice/users/4977dae1-a307-425f-980c-53413fef1b0f",
"when_audited": "2018-11-13T20:20:39+00:00",
"what_uri": "test.com/dataservice/study_subjects/1bc67a71-8549-4ab8-9dd9-e44238198860",
"what_changed": [
{
"attribute_name": "birth_year",
"attribute_value": "1969",
"attribute_change": "1970"
},
{
"attribute_name": "subject_reference",
"attribute_value": "TEST-WOO3444",
"attribute_change": null
}
]
}
}
And I want to remove the second attribute_change key value pair to be as follows
{
"audit_date": "2020-05-13T11:27:10.3187798Z",
"client_uuid": "2fd77dd8-ed76-4bba-b0e1-5cda454c8d6e",
"audit_entry": {
"where_uri": "test.com/dataservice/apps/171f0841-825b-4964-8f8c-0869650f14a6",
"why_uri": "test.com/dataservice/reference/reasons_for_change/61acc173-7168-4ae5-9f04- afa228941f8b",
"who_uri": "test.com/securityservice/users/4977dae1-a307-425f-980c-53413fef1b0f",
"when_audited": "2018-11-13T20:20:39+00:00",
"what_uri": "test.com/dataservice/study_subjects/1bc67a71-8549-4ab8-9dd9-e44238198860",
"what_changed": [
{
"attribute_name": "birth_year",
"attribute_value": "1969",
"attribute_change": "1970"
},
{
"attribute_name": "subject_reference",
"attribute_value": "TEST-WOO3444",
}
]
}
}
I have tried the following code
JObject jObject = JObject.Parse(jsonText);
JObject jObj = (JObject)jObject.SelectToken("audit_entry");
//remove second attribute changed token
jObj.Property("what_changed")("attribute_change")[1].Remove();
string json = jObj.ToString(Formatting.None);
I know the syntax is wrong for jObj.Property but after a few hours of googling I cannot find the answer.
Any help much appreciated.
You can remove a property from JObject by calling Remove method with corresponding property name. For example:
JObject jObject = JObject.Parse(jsonText);
// find required object, there are other options
// for example (JObject)jObject["audit_entry"]["what_changed"][1]
var nested = (JObject)jObject.SelectToken("$.audit_entry.what_changed[1]");
//remove attribute changed token
nested.Remove("attribute_change");
string json = jObject.ToString(Formatting.None); // attribute_change is removed from jObject
If you want to remove all properties with such name and null for value you can do next:
var toRemove = jObject.Descendants()
.OfType<JProperty>()
.Where(prop => prop.Name == "attribute_change" && prop.Value.Type == JTokenType.Null)
.ToList();
foreach (var prop in toRemove)
{
prop.Remove();
}
Since what_changed is an array, you should cast to JArray to be able to access its elements and remove attribute_change token
var jObject = JObject.Parse(jsonText);
if (jObject["audit_entry"]?["what_changed"] is JArray array)
if (array[1] is JObject attribute)
attribute.Remove("attribute_change");
Console.WriteLine(jObject);
Search for the beginning attribute name and its end. Then concatenate the json string before/after into a new string. Perhaps a hack, but it will keep you coding until you find a more elegant solution.
I have a JSON string like below:
{
"MetaData": {
"ResourcesUsed": 1
},
"Result": [
{
"locations": [
{
"country": "Papua New Guinea",
"city": "Jacquinot Bay",
"locTypeAttributes": {
"localDate": "2018-10-08T04:21:00-07:00",
"utcDate": "2018-10-08T04:21:00-07:00",
},
"point": {
"coordinates": [
151.52,
-5.6
],
"type": "Point"
}
},{
"country": "Papua New Guinea2",
"city": "Jacquinot Bay2",
"locTypeAttributes": {
"localDate": "2018-10-08T04:21:00-07:00",
"utcDate": "2018-10-02T04:21:00-07:00",
},
"point": {
"coordinates": [
151.52,
-5.6
],
"type": "Point"
}
}
]
}
]
}
I converted it to a JSON object using Newtonsoft. What I want to do is to sort the locations array(s) inside the Result array by the utcDate field nested in each locations item. I found the following thread: C# Sort JSON string keys. However, I could not still implement it since I have arrays inside my object, while that question deals purely with sorting objects inside objects alphabetically by property name.
Here is a piece of code that I wrote so far:
public string GenerateJson()
{
var model = (JObject)JsonConvert.DeserializeObject(data);
Sort(model);
}
private void Sort(JObject jObj)
{
var props = jObj["Result"][0]["locations"].ToList();
foreach (var prop in props)
{
prop.Remove();
}
foreach (var prop in props.OrderBy(p => p.Name))
{
jObj.Add(prop);
if (prop.Value is JObject)
Sort((JObject)prop.Value);
if (prop.Value is JArray)
{
Int32 iCount = prop.Value.Count();
for (Int32 iIterator = 0; iIterator < iCount; iIterator++)
if (prop.Value[iIterator] is JObject)
Sort((JObject)prop.Value[iIterator]);
}
}
}
You can sort each individual "Result[*].locations" array using LINQ as follows:
// Load the JSON without parsing or converting any dates.
var model = JsonConvert.DeserializeObject<JObject>(data, new JsonSerializerSettings{ DateParseHandling = DateParseHandling.None });
// Construct a serializer that converts all DateTime values to UTC
var serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings{ DateTimeZoneHandling = DateTimeZoneHandling.Utc });
foreach (var locations in model.SelectTokens("Result[*].locations").OfType<JArray>())
{
// Then sort the locations by utcDate converting the value to UTC at this time.
var query = from location in locations
let utcDate = location.SelectToken("locTypeAttributes.utcDate").ToObject<DateTime>(serializer)
orderby utcDate
select location;
locations.ReplaceAll(query.ToList());
}
Notes:
The JSON is initially loaded using DateParseHandling.None to prevent the "localDate" and "utcDate" strings from being prematurely interpreted as DateTime objects with a uniform DateTime.Kind.
(For a discussion of how Json.NET interprets strings that look like dates, see Serializing Dates in JSON.)
We then iterate through all "locations" arrays using SelectTokens("Result[*].locations") where [*] is the JSONPath wildcard character, selecting all entries in the "Results" array.
We then order each "locations" array by deserializing the nested locTypeAttributes.utcDate to a UTC date, then ordering using LINQ.
Finally the array is updated using JArray.ReplaceAll().
If any locTypeAttributes.utcDate property is missing, an exception will be thrown. You could instead deserialize to DateTime? if that is a possibility.
Working sample .Net fiddle here.
I have this json string:
[
[
{
"Antibiotic after diagnosis":[
"Azithromycin",
"Ciprofloxacin HCl",
"Ampicillin Sodium"
],
"City":[
"Tel Aviv",
"Jerusalem"
]
}
],
[
{
"Antibiotic after diagnosis":"Azithromycin",
"City":"Tel Aviv"
},
{
"Antibiotic after diagnosis":"Ciprofloxacin HCl",
"City":"Jerusalem"
}
]
]
I deserialized this string:
data = Newtonsoft.Json.JsonConvert.DeserializeObject<List<object>>("*json str*");
JParameters = data[0] as JArray;
Debug.Log(JParameters["Antibiotic after diagnosis"]);
But when i run the code it crashed on the line (Debug.Log(JParameters["Antibiotic after diagnosis"]);) with the following error:
"ArgumentException: Accessed JArray values with invalid key value: "Antibiotic after diagnosis". Int32 array index expected."
The index into JParameters should be an integer as the error states. What you want is:
JParameters[0]["Antibiotic after diagnosis"]
The above code selects the first element, and then selects the value for the dictionary key "Antibiotic after diagnosis".
I recommend reading w3schools JSON to properly understand how JSON works.
One option is to get key, value from Jproperty.
var files = JArray.Parse(YourJSON);
foreach (JArray item in files.Children())
{
foreach (JObject obj in item.Children())
{
foreach (JProperty prop in obj.Children())
{
string key = prop.Name.ToString();
string value = prop.Value.ToString();
}
}
}
i have json in object.
{
"data": [
{
"name": "Diljeet Jamwal",
"uid": 553042280,
"pic_square": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/274654_553042280_2105727599_q.jpg"
}, {
"name": "Jatinder Sharma",
"uid": 553042280,
"pic_square": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/274654_553042280_2105727599_q.jpg"
}]}
i want to show this in list in C#, how to do.
foreach (string data in yourlist)
{
console.WriteLine(data);
}
Of course do the parsing job to fill your list before ;)
You can try Newtonsoft.Json library http://nuget.org/packages/newtonsoft.json/
Example:
String yourdata = "..." // your JSON response
JObject json = JObject.Parse(yourdata);
after this, you can access your data:
String name = json["data"][0]["name"] //it should be Diljeet Jamwal
thanks to all, i have done this
dynamic array = JsonConvert.DeserializeObject(result.ToString());
foreach (var item in array)
{
foreach (var name in item["data"])
{
Response.Write(name["name"]);
}
}
using this