how to add an empty array to a json payload? - c#

Is it possible to add an array to a json payload?
For example, let's say this is my payload:
string json = #"{
'channel': {
'title': 'Star Wars',
'link': 'http://www.starwars.com',
'description': 'Star Wars blog.',
'obsolete': [{'something':'awesome'},{'a':'b'}],
'item': [],
'nested':[{'upgrademe':'please'}, {'upgrademe':'no'}]
}
}";
The result I'd like would be something like this:
string json = #"{
'channel': {
'title': 'Star Wars',
'link': 'http://www.starwars.com',
'description': 'Star Wars blog.',
'obsolete': [{'something':'awesome'},{'a':'b'}],
'item': [],
'nested':[{'upgrademe':'please', 'emptyArray':[]}, {'upgrademe':'no'}]
}
}";
For every channel.nested where upgrademe == please then I'd like to add an empty array like [].
before:
'nested':[{'upgrademe':'please'}, {'upgrademe':'no'}]
after:
'nested':[{'upgrademe':'please', 'emptyArray':[]}, {'upgrademe':'no'}]
My current implementation:
public static JObject AddArray(this JObject jObject, string path, string key, string value)
{
var obs = jObject.SelectToken(path);
if (obs == null)
{
return jObject;
}
foreach (var jsonObject in obs)
{
if (jsonObject.SelectToken(key).ToString().ToLower() != value.ToLower())
{
continue;
}
jObject.SelectToken(path).Parent.AddAfterSelf(new JValue(new JProperty("emptyArray", new JArray())));
}
return jObject;
}
I'm getting an exception on this line:
usage example:
var result = jobject.AddArray("channel.nested", "upgrademe", "please");
the above says the following:
find the object "channel.nested" and when upgrademe==please, add a sibbling node as an empty array
How do we conditionally add an array object to a json payload?

Since you're adding a new property into an object. You don't need to use JValue
Just use JProperty directly:
AddAfterSelf(new JProperty("emptyArray", new JArray()))

Related

Not Able to Parse ServerEventMessage from ServiceStack to C#

I Am able to get first level of JSON but not second.
I am getting JSON from Here -
var client = new ServerEventsClient(baseUri) {
OnMessage = e => analysedata(e),
}.Start();
And in this functin, I am trying to parse -
public string analysedata(ServerEventMessage test)
{
var parsed = (JObject)JsonConvert.DeserializeObject(JsonConvert.SerializeObject(test));
string p1 = parsed["Data"].Value<string>();
}
Now p1 should be a string? But it is of type - Newtonsoft.Json.Linq.JValue
parsed["Data"] is JSON response sent by my server.
If I do parsed["Data"]["event_id"] Debug.Writeline does not print anything in output.
Documentation - https://docs.servicestack.net/csharp-server-events-client#assigning-callback-handlers
use JObject.Parse to parse the json
public string analysedata(ServerEventMessage test)
{
var parsed = JObject.Parse(test.Json));
string p1 = parsed["Data"].Value<string>();
}
For the usage of JObject, you could check the code below. I used a JSON string for reference.
string json = #"{
'channel': {
'title': 'James Newton-King',
'link': 'http://james.newtonking.com',
'description': 'James Newton-King\'s blog.',
'item': [
{
'title': 'Json.NET 1.3 + New license + Now on CodePlex',
'description': 'Announcing the release of Json.NET 1.3, the MIT license and the source on CodePlex',
'link': 'http://james.newtonking.com/projects/json-net.aspx',
'categories': [
'Json.NET',
'CodePlex'
]
},
{
'title': 'LINQ to JSON beta',
'description': 'Announcing LINQ to JSON',
'link': 'http://james.newtonking.com/projects/json-net.aspx',
'categories': [
'Json.NET',
'LINQ'
]
}
]
}
}";
JObject rss = JObject.Parse(json);
string rssTitle = (string)rss["channel"]["title"];
// James Newton-King
string itemTitle = (string)rss["channel"]["item"][0]["title"];
// Json.NET 1.3 + New license + Now on CodePlex
JArray categories = (JArray)rss["channel"]["item"][0]["categories"];
// ["Json.NET", "CodePlex"]
IList<string> categoriesText = categories.Select(c => (string)c).ToList();
// Json.NET
// CodePlex
Since you're already using ServiceStack, using its JS Utils is the recommended way to parse arbitrary json, e.g:
var obj = (Dictionary<string,object>) JSON.parse(json);

SelectToken() with parenthesis in jToken throwing "Unexpected character while parsing path indexer" error

I'm trying to deserialize and parse a JsonObj
{ "obj": [
{
"name": "Kelly",
"calculation": {
"reff" : "apply(stringa/stringb)"
},
"value": "Number",
}
]
}
string jsonString = JsonConvert.SerializeObject(jsonObj);
JObject parsedObj = JObject.Parse(jsonString );
var reffTokens = parsedObj.SelectTokens("$..reff");
foreach (JToken token in reffTokens.ToArray())
{
var calculatedToken = parsedObj.SelectToken(token.ToString());
}
I get this error:
Newtonsoft.Json.JsonException
HResult=0x80131500
Message=Unexpected character while parsing path indexer:
Source=Newtonsoft.Json
If I remove the braces and have the calculation part as
"calculation": {
"reff" : "stringa/stringb"
},
then it works fine. any suggestion on how to deserialize and parse JObject for parentheses? Thanks!

How to remove a key value pair within a nested json structure in C#

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.

Passing Array from Javascript to C#

I have a .js script that contain an array:
The output of the js is like:
var foo=
[
{
"bar1":"value1",
"bar2":"value2"
// And so on...
}
]
I have no access to the js source, so i cannot output as JSON and Deserialize.
I can only get this as a String using WebClient, but how i can parse it and create an Array/Dictionary and work on it inside C#?
You should consider calling WebClient.DownloadString . Then Parse using JSON.Net or whatever
As per the example provided over there
string json = #"{
""Name"": ""Apple"",
""Expiry"": "2008-12-28T00:00:00",
""Price"": 3.99,
""Sizes"": [
""Small"",
""Medium"",
""Large""
]
}";
JObject o = JObject.Parse(json);
string name = (string)o["Name"];
// Apple
JArray sizes = (JArray)o["Sizes"];
string smallest = (string)sizes[0];
// Small
var foo = new JavaScriptSerializer().Deserialize<List<YourModelHere>>(YourString);
You can use a JavaScriptSerializer to deserialize that string:
string str=
#"var foo =
[
{
""bar1"":""value1"",
""bar2"":""value2""
}
]";
JavaScriptSerializer js = new JavaScriptSerializer();
var o = js.Deserialize<Dictionary<string,string>[]>(str.Substring(str.IndexOf('[')));
Result:
Dictionary<String,String> (2 items)
Key Value
------ --------
bar1 value1
bar2 value2

Json.net how to use jsonpath with "$."

I'm trying to use json.net from json as follows:
String JSONString =
#"[
{
""category"": ""reference"",
""author"": ""Nigel Rees"",
""title"": ""Sayings of the Century"",
""price"": 8.95
},
{
""category"": ""fiction"",
""author"": ""Still Here"",
""title"": ""Test remove title"",
""price"": 12.99,
""isbn"": ""0-553-21311-3""
}
]";
JObject JSONObject;
JSONObject = JObject.Parse(JSONString);
String JSONPath = #"$[0].title";
JSONObject.SelectToken(JSONPath);
Getting Exception:
ST.Acxiom.Test.DataJSONTest.DataJSONClass.GetToken: Newtonsoft.Json.JsonException : Property '$' does not exist on JObject.
What I'm doing wrong, even though I'm using valid jsonpath but still
getting error.
Is "$." not supported?
How to access Array item in
json in above example?
Any help would be appreciated.
Using JObject.Parse from your example throws JsonReaderException with the latest Json.net version. You have to use either JToken.Parse or JsonConvert.DeserializeObject.
SelectToken is intended to select child nodes so $ is not supported. You can access array item like this:
var jArray = JToken.Parse(JSONString); //It's actually a JArray, not a JObject
var jTitle = jArray.SelectToken("[0].title");
var title = (string)jTitle;

Categories

Resources