Retrieve JObject member from a JArray using SelectToken - c#

I have the following json parsed into a JObject:
JObject json = JObject.Parse(#"{
""event"": {
""name"": ""daniel""
},
""markets"": [
{}
]
}");
With that JObject I'm trying to retrieve the empty JObject that's in the markets JArray.
I'm currently trying json.SelectToken("$.event.markets[0]") but that's not working, it returns null rather than the empty JObject that I expect.
Is there a way to get that empty JObject by using the SelectToken || SelectTokens method? I'd prefer to stay away from using linq, but if I must I must.

This should be json.SelectToken("$.markets[0]") instead of json.SelectToken("$.event.markets[0]") as markets is not contained within the event object.

Related

How to use JObject.SelectToken to parse json properties that start with #?

Given the following json:
{
"Test": {
"#id": "abcdef"
}
}
How can I use JObject.SelectToken() to retrieve the value of #id?
I've tried:
JObject jobject = JObject.Parse(json);
jobject.SelectToken("Test.#id").Value<string>()
jobject.SelectToken(#"Test.\#id").Value<string>()
jobject.SelectToken("[Test].[#id]").Value<string>()
jobject.SelectToken(#"[Test].[\#id]").Value<string>()
I managed to get it to work using:
jobject.SelectToken("Test['#id']").Value<string>()
The important part is the single quotes from what I can tell.

How to empty a JObject array 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": null
},
{
"attribute_name": "subject_reference",
"attribute_value": "TEST-WOO3444",
"attribute_change": null
}
]
}
}
But I want to empty the nest array "what_changed"
So I need the output to be
{
"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": []
}
}
I have written the following code
JObject jObj = JObject.Parse(jsonText);
jObj["audit_entry"]["what_changed"] = null;
string json = jObj.ToString(Formatting.None);
but this makes the field null rather than empty array.
I have also tried
JObject jObj = JObject.Parse(jsonText);
jObj["audit_entry"]["what_changed"] = "";
string json = jObj.ToString(Formatting.None);
but that still doesn't give an empty array.
I also tried using the Array.Clear() method, but this is a JObject array rather than a normal array.
Arrays are represented by the JArray type, not JObject. Cast the value of "what_changed" to the proper type and use the methods you need. Eg:
JObject jObj = JObject.Parse(jsonText);
JArray changed=(JArray)(jObj["audit_entry"]["what_changed"]);
changed.Clear();
Working with JSON elements is rather unusual though. It's typically a lot easier to deserialize JSON strings into strongly typed objects, modify them as needed and then serialize them back to a string.
Generating the necessary DTOs can be done easily in Visual Studio by selecting Paste Special > Paste JSON as Classes from the Edit menu
I can see several possibilities...
1.- instead of clearing the array, create a new one, an empty one. This does not solve the problem but it is a work around.
2.- using newtonsoft (a nuget package that you can download), you may be able to find different utilities there.
2.1.- Instead of parsing with JObject, parse with JArray, and then use Clear:
https://www.newtonsoft.com/json/help/html/ParseJsonArray.htm
https://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JArray_Clear.htm.
2.2.- use Remove, for this you need the property name, so you need to iterate within the array (a foreach), getting the name of the property, and delete one by one.
https://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JObject_Remove.htm
You need to cast it to a JArray first, then you can use its Clear() method;
((JArray)(jObj["audit_entry"]["what_changed"])).Clear();
Alternatively, you could simply create a new JArray in place of the old one.
jObj["audit_entry"]["what_changed"] = new JArray();
Try this :
JObject jObj = JObject.Parse(jsonText);
JToken jToken = jObj["audit_entry"]["what_changed"];
jToken.Replace(JToken.Parse("[]"));
string json = jObj.ToString(Formatting.None);

Unable to find certain data(json objects) in json response with JProperty

I'm trying to debug my JProperty object but somehow I can not get all the data out of this object. When I debug te JProperty it says it has the data im trying to recieve but I'm only able to obtain a part of it, explanation:
So my response JSON looks like this:
{"url":"www.microsoft0nline.nl\/test.php","time":"2019-06-19 09:50:49","stringvalue":"otherValue1","intvalue":433,"array":["35","37","43"],"otherObject1":{"name":"object1","description":"A object type","size":120}}
I'm iterating through this with the following code:
foreach (JProperty property in jsonResponse.Properties())
{
}
So when I run my code in debug mode and i debug these properties I'm getting the following:
As you all can see the parent of property has the object "otherObject1" within.
Now I iterate through this property with the following code:
foreach (var itemsOfResponse in property)
{
var dataJson = itemsOfResponse;
System.Diagnostics.Debug.WriteLine(dataJson);
}
And the response in my debugger looks like this:
www.microsoft0nline.nl/test.php
2019-06-19 10:01:49
otherValue1
433
[
"35",
"37",
"43"
]
The response contains all the values of my json response exept the one of "otherObject1", how is this possible? And is there a way to obtain the key values(url, stringvalue, intvalue, etc) of these properties to?
Hope someone can help me out here!
JProperty is only a single name value token pair.
JObject will contain many JToken objects (including JProperty and JObject instances).
For what you are trying to do, you should probably use JToken as both JProperty and JObject are JToken derived classes.

Build JObject from JSONPath

I'm a bit new to using the Newtonsoft JSON library for .NET. Is there any way to create a JObject or JToken from a JSONPath?
So for example something like the following.
string jsonPath = "$.ArrayA[0].ArrayB[0].Property";
JObject jObj = JObject.FromJSONPath(jsonPath); // SOMETHING LIKE THIS
The result would be a JObject or JToken that looks like this.
{
"ArrayA": [{
"ArrayB": [{
"Property": ""
}]
}
}
No.
If you have some existing JSON, you can parse it to a JToken and then select one or more descendant JTokens from it using SelectToken or SelectTokens with a JsonPath expression. For example:
string json = #"{ ""ArrayA"": [{ ""ArrayB"": [{ ""Property"": ""foo"" }] }] }";
JToken token = JToken.Parse(json);
JToken fooToken = token.SelectToken("$..Property");
Console.WriteLine(fooToken.ToString()); // prints "foo"
You can also manually build a nested structure of JTokens. For example, you can create the JObject in your question like this:
var obj = new JObject(new JProperty("ArrayA", new JArray(
new JObject(new JProperty("ArrayB", new JArray(
new JObject(new JProperty("Property", ""))))))));
However, there is no built-in way to create a JToken from nothing but a JsonPath expression. You would need to roll your own method to do something like that. But keep in mind that JsonPath was designed as a query mechanism; it doesn't map cleanly to creation of new objects. Here are some issues you would need to think about:
In your example expression, $.ArrayA[0].ArrayB[0].Property, what type is Property? Is it string, number, boolean, object or an empty array? How would you specify that?
How would you specify creation of an object with multiple properties?
What would an expression like $..book[(#.length-1)] create?

Deserialize JSON with json.NET into C# dynamic

I have following problem: I have a json file that looks like this
{
"Path": {
"FirstPath": "/1/2/text()"
}
}
If I parse this JSON-File with Newtonsoft like this
dynamic dyn = JObject.Parse(json);
or this
dynamic dyn = JsonConvert.DeserializeObject(json);
I get a dynamic object that needs to be used like this
dyn.Path.FirstPath.Value
How can I get rid of the Value stuff? All of my objects in the JSON end up being a string. I don't want to always write ".Value" at the end if it is not necessary.
I tested this using Newtonsoft 8.0.2 and it works fine.
dynamic dyn = JObject.Parse(json);
string value = dyn.Path.FirstPath;
Value should equal /1/2/text().

Categories

Resources