I might be a simple question but I'm trying to access some specific key value pair from a JToken. This JToken is all key value pair as well. For example:
"name": "Someone",
"UTC": "2028-01-20T13:32:26",
"localtime": "2028-01-20T12:32:14",
"CUSTOM.datastoreversion": "70",
"CUSTOM.swversion": "1804201116",
"CUSTOM.apiversion": "1.25.0",
Some property contains a prefix "CUSTOM.", is there any way to filter out these elements in the JToken so I can only look at those properties and values instead?
Update:
- I don't intend to modify the original jtoken data.
- I only want to figure out how to get property names and values from jtoken data.
CodePudding user response:
I would convert the string to a JObject
& use that instead of a JToken
- JToken
is the base class for JObject
, JArray
, etc. so even if a method takes in a JToken
, you can pass the JObject
& it'll work just fine.
That aside, after converting the input to a JObject
, we can then loop over the JSON keys and values as it implements IEnumerable<KeyValuePair<string, JToken>>
.
Looping over the keys, we then check to see if there are any keys that don't start with CONTAINS.
If such key(s) exists, we remove the property entirely based on the key name, from a deep clone copy. We have to use a copy as in general, we cannot modify a collection & enumerate over it at the same time (or it'll throw a System.InvalidOperationException: 'Collection was modified; enumeration operation may not execute.'
).
The below works pretty nicely as an extension method.
string testData = "{\"name\":\"Someone\",\"UTC\":\"2028-01-20T13:32:26\",\"localtime\":\"2028-01-20T12:32:14\",\"CUSTOM.datastoreversion\":\"70\",\"CUSTOM.swversion\":\"1804201116\",\"CUSTOM.apiversion\":\"1.25.0\"}";
var jObject = JObject.Parse(testData);
var filteredJToken = jObject.FilterJObjectToPropertiesWithPrefix("CUSTOM.");
foreach (var (key, value) in filteredJToken)
Console.WriteLine($"{key} : {value}");
...
JObjectExtensions.cs
public static class JObjectExtensions
{
public static JObject FilterJObjectToPropertiesWithPrefix(this JObject source, string prefix)
{
var jObject = source;
var jObjectCopy = (JObject)jObject.DeepClone();
foreach (var (key, jTokenValue) in jObject)
{
if (!key.StartsWith(prefix))
jObjectCopy.Remove(key);
}
return jObjectCopy;
}
}
Output:
CUSTOM.datastoreversion : 70
CUSTOM.swversion : 1804201116
CUSTOM.apiversion : 1.25.0
CodePudding user response:
try this
var list = JsonConvert.DeserializeObject<Dictionary<string, string>>(json).ToList();
var customs=list.Where(j => j.Key.StartsWith("CUSTOM."));
//or
var customs=list.Where(j => j.Key.Contains("CUSTOM."));
customs
CUSTOM.datastoreversion 70
CUSTOM.swversion 1804201116
CUSTOM.apiversion 1.25.0
how to use (example)
var customsData= list.Where(j => j.Key.Contains("CUSTOM.data"))
.Select(j =>j.Value ).FirstOrDefault();
output
70