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

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.

Related

Removing object using JArrayItem.Remove("value") not working

I am trying to remove an object from an existing JArray, but when I run the method to delete the property from the JArray, the property still exists.
I tried simply using the code below
JObject rss1 = JObject.Parse(File.ReadAllText("online.json"));
JObject uList = (JObject)rss1["uList"];
JArray newOnline = (JArray)uList["online"];
newOnline.Remove("value");
The code above is almost directly copied and pasted from the Newtonsoft.Json documentation on modifying Json, but only changed to remove the new item instead of adding it. I've tried other post's solutions, but none of them work. Adding the field works as expected, but trying to remove it does not work whatsoever.
Below is the JSON file's contents
{
"uList": {
"placeHolder": "placeHolderValue",
"online": [
"value"
]
}
}
Below is the expected JSON output of the code being ran
{
"uList": {
"placeHolder": "placeHolderValue",
"online": [
]
}
}
And, below, is the actual output of the code being ran
{
"uList": {
"placeHolder": "placeHolderValue",
"online": [
"value"
]
}
}
Am I doing something wrong and not realizing it?
The problem you've got is that you don't actually have a string in your array, you have a JValue. The JArray.Remove method accepts a JToken, but the JToken produced by implicitly casing your string to a JValue is not equal to the one being removed.
There's one of two solutions that come to mind:
Find the item in the array and then pass that to the remove method:
JToken item = newOnline.FirstOrDefault(arr => arr.Type == JTokenType.String && arr.Value<string>() == "value");
newOnline.Remove(item);
Use the .Remove method of the array item to remove it from the array:
JToken item = newOnline.FirstOrDefault(arr => arr.Type == JTokenType.String && arr.Value<string>() == "value");
item?.Remove();
You can also remove JToken by querying value string present in online JArray.
Parse string to JObject:
JObject rss1 = JObject.Parse(File.ReadAllText("online.json"));
Now remove particular token using below query.
rss1.SelectTokens("$.uList.online[?(# == 'value')]").FirstOrDefault()?.Remove();
Try online

Retrieve JObject member from a JArray using SelectToken

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.

Trying to deserialize JSON with surrounding [] characters usig JSON.NET

I am using .NET 4.7, C#, JSON.NET, MVC 5
I have some input JSON:
[
{
"id" : 1
},
{
"id" : 2
},
{
"id" : 3
}
]
This is provided by a 3rd party API
Normally I would use code such as, to deserialize:
var content = await response.Content.ReadAsStringAsync();
JObject json = JObject.Parse(content);
orderList = JsonConvert.DeserializeObject<OrderList>(json.ToString());
However I am finding that:
JObject json = JObject.Parse(content);
Crashes out with the JSON in question. I strongly suspect that the surrounding "[" and "]" is the cause.
I would normally add :
{
items: [
to correct the input JSON.
Is there a better way, to deserialize it, as it seems this input JSON is incomplete although when I test it, it does seem to be valid JSON.
Possibly I should be using JArray instead of JObject?
Thanks in advance.
You are missing commas "," in the JSON. It should be like this:
[
{
"id" : 1
},
{
"id" : 2
},
{
"id" : 3
}
]
And you can deserialize it like that:
var content = await response.Content.ReadAsStringAsync();
var list = JsonConvert.DeserializeObject<List<MyClass>>(content);
Where list is a List<MyClass>
public class MyClass
{
public int id { get; set; }
}
You have 3 options:
Instead of JObject.Parse, use JArray.Parse because the JSON is an array, not an object. This is not the best way to achieve what you want.
Deserialise to a List<T> where T is a concrete class that contains the matching properties of the object. for example:
var result = JsonConvert.DeserializeObject<List<Order>>(json);
This is better, but...
The best option is not to read the HttpClient response as a string in the first place and let the framework do the work for you. You should use the ReadAsAsync<T> extension method. Internally, this uses a stream and is more efficient than first going to string. So for example:
List<Order> orders = await response.Content.ReadAsAsync<List<Order>>();

Addressing JSON in C# dynamically

I wish to write some C# which allows the client to provide a JSON string and query string. The query string would then be used to address values in the JSON object.
For example, if I had this JSON:
{
"head": "big",
"fingers": [
"one", "thumb",
"two", "ring"
],
"arm": {
"elbow", "locked"
}
}
And this query string:
"fingers.two"
I would want to return the value "ring".
Is this (or something like it) possible in C#?
I have tried using the ExpandoObject class, but this does not allow dynamic runtime inspection:
var json = JsonConvert.DeserializeObject<ExpandoObject>(jsonStr);
As far as I can tell, the discovery of values on the json variable needs to be done at code time, rather than runtime, which means I cannot dynamically find values being queried for.
JSONPath does this
Assuming the following JSON (fixed a few syntax errors in the original)
{
"head": "big",
"fingers": {
"one":"thumb",
"two":"ring"
},
"arm": {
"elbow": "locked"
}
}
And this query
MyJObjectOrToken.SelectToken("fingers.two")
You will get the following output:
[
"ring"
]
It should be trivial then to extract the value as a string using JSON.Net methods and return the result to your user.
Support for JSONPath is built into JSON.Net
https://www.newtonsoft.com/json/help/html/SelectToken.htm

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