I make a POST request and I get back json response with a lot of transactions in it like:
"Transactions": [
{
"ID": "1",
"Name" : "name",
"Code": "123aaa"
},
{
"ID": "2",
"Name" : "name1",
"Code": "12345bbb"
}
]
Is there any simple way to get one variable (for example first "Code" value)? Without entity classes etc?
I've tried this
var content = new StringContent(request, Encoding.UTF8, "application/json");
var response = await HttpClient.PostAsync(postURL, content);
var text = await response.Content.ReadAsStringAsync();
var code = JObject.Parse(text).Children().First().Values<string>("Code").First();
But it didn't work:
System.InvalidOperationException : Cannot access child value on Newtonsoft.Json.Linq.JValue.
Assuming that provided json is actually an object (i.e. string in question is wrapped in curly brackets) - you can use json path:
var code = JObject.Parse(text).SelectToken("$.Transactions[0].Code").ToString(); // results in "123aaa"
If you are keen on using LINQ to JSON you can do something like this:
var code = JObject.Parse(text)
.Descendants()
.OfType<JProperty>()
.Where(p => p.Name == "Code")
.Select(p => p.Value.ToString())
.FirstOrDefault();
But the easiest I think would be to use indexers:
var code = JObject.Parse(text)["Transactions"][0]["Code"].ToString();
Related
Using NewtonSoft, I am able to parse JSON into this:
var jtoken = JObject.Parse(stringStuff);
Console.WriteLine(jtoken.ToString());
gives this:
{
"data": {
"user": {
"email": "john#doe.com",
"external-id": "af36-e9fddecdb755"
},
"session-token": "G_uJNNxmLNtxcmM2ilB6P_dN67p9XXk3-yn8peUBi7k3xH50Ch7MUQ+C"
},
"context": "/sessions"
}
However, if I try to get the field "session-token" like this,
var token = jtoken.Value<string>("session-token");
token is null. Not sure what I am doing wrong?
a "session-token" property is nested inside of a "data" property
string token = (string) jtoken["data"]["session-token"]; // G_uJNNxmLNtxcmM2ilB6P_dN67p9XXk3-yn8peUBi7k3xH50Ch7MUQ+C
You need to run through the descendants of your root object, and find the JProperty with the name you want -
var token = root.Descendants()
.OfType<JProperty>()
.Where(x => x.Name == "session-token")
.FirstOrDefault()
?.Value
?.Value<string>();
if(token != null)
{
//token is "G_uJNNxmLNtxcmM2ilB6P_dN67p9XXk3-yn8peUBi7k3xH50Ch7MUQ+C"
}
It's a little awkward, the first .Value returns the JProperty's JToken, then the second .Value gets the string value.
I am trying to get only Unique IDs from a JSON response. I tried to parse and select only token Ids but it is failing. What is the best and fastest way to get only the Ids?
Code:
JArray jArray = new JArray();
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
response.Content = new StringContent(jArray.ToString(Formatting.Indented));
var resp = await response.Content.ReadAsStringAsync();
Here is my sample JSON Array:
[
{
"Timestamp": "2020-11-24T08:25:46.6531855Z",
"ID": "8c316aca-b930-421f-851c-17d618b61fa1",
"Message": "New User Registered"
},
{
"Timestamp": "2020-11-24T08:25:46.6531855Z",
"ID": "8c316aca-b930-421f-851c-17d618b61fa1",
"Message": "User details updated"
},
{
"Timestamp": "2020-11-24T08:25:46.6531855Z",
"ID": "a23shaga-2wd3-fky6-851c-43524fbfgsa",
"Message": "New User Registered"
}
]
Desired Output:
8c316aca-b930-421f-851c-17d618b61fa1
a23shaga-2wd3-fky6-851c-43524fbfgsa
This will give you the distinct ID values from your JArray, filtering out possible nulls:
jArray = JArray.Parse(resp);
var ids = jArray.Children<JObject>()
.Select(jo => (string)jo["ID"]) // NOTE: this is case sensitive
.Where(s => s != null)
.Distinct()
.ToList();
Demo here: https://dotnetfiddle.net/gaQ1n0
Best way is to create the object with the properties timestamp, id and message- then deserialize the json to this object.
But for now you can try below and should work out well for you.
JArray jArray = new JArray();
jArray = JArray.Parse(#"[
{
""Timestamp"": ""2020-11-24T08:25:46.6531855Z"",
""ID"": ""8c316aca-b930-421f-851c-17d618b61fa1"",
""Message"": ""New User Registered""
},
{
""Timestamp"": ""2020-11-24T08:25:46.6531855Z"",
""ID"": ""8c316aca-b930-421f-851c-17d618b61fa1"",
""Message"": ""User details updated""
},
{
""Timestamp"": ""2020-11-24T08:25:46.6531855Z"",
""ID"":""a23shaga-2wd3-fky6-851c-43524fbfgsa"",
""Message"": ""New User Registered""
}]");
var newList = jArray.Where(y=> !string.IsNullOrEmpty(y["ID"].ToString()))
.GroupBy(x => x["ID"])
.Select(x => x.First()).ToList();
foreach (var item in newList)
{
Console.WriteLine(item["ID"]);
}
Here newList contains only unique data w.r.t 'ID'
Just replace the entire string in my example with the async resp you are getting.
NOTE : You should either make the source return unique or create a new object and deserialize it instead of using JObject, this will help you when you have bigger lists
So below is the outcome i think you are looking for
I have been building an application where JSON will be provided from a user API. It should read the data from the JSON using JSONPath and persist the selected portions. I am trying to do this using Json.Net (Newtonsoft). The following JSON is a sample:
{
// other properties here and different structure here
"Data": [
{
"Code": "625087",
"Name": "Customer Name",
"Email": "test#hfgidfgd.com"
},
{
"Code": "625087",
"Name": "Customer Name",
"Email": "test#hfgidfgd.com"
},
{
"Code": "625087",
"Name": "Customer Name",
"Email": "test#hfgidfgd.com"
}
],
// other properties here and different structure here
}
I would like to extract the array presented by the Data property content using JSONPath and convert it to List<Dictionary<string, object>> to manipulate in my application.
In tools like jsonpath.com the following JSONPath query works fine but with Newtonsoft it does not:
// get that json
string content = GetJson();
var jo = JObject.Parse(content);
var jsonPath = "$..Data.*";
var jsonPathResult = jo.SelectTokens(jsonPath, true /* to get error when it is not found */ );
Instead I got the exception:
Property '*' not valid on JArray.
If I do the JSONPath like this:
var jsonPath = "$..Data"; // same for just: "Data"
var jsonPathResult = jo.SelectTokens(jsonPath);
I have to loop on the result with two nested foreach, what I think it is not an elegant solution:
var result = new List<Dictionary<string, object>>();
foreach (var jsonResult in jsonPathResult)
{
foreach (var item in jsonResult)
{
var fields = JsonConvert.DeserializeObject<Dictionary<string, object>>(item.ToString());
// some adjusts on the fields dictionary will be applied here...
result.Add(fields);
}
}
Is there any way to get the result to take a single loop the only the content of Data property?
As shown in JSONPath - XPath for JSON, the syntax for an array element wildcard is [*]. Thus your code should look like:
var jsonPath = "$..Data[*]";
var result = jo.SelectTokens(jsonPath, true /* to get error when it is not found */ )
.Select(o => o.ToObject<Dictionary<string, object>>())
.ToList();
Here I am using JToken.ToObject<T>() to deserialize each array element directly to a Dictionary<string, object>> without re-serializing to a string.
Sample working .Net fiddle.
I got the json response from dialogflow. Now I want to get the "q1" value. So I've tried this:
var stringjson = ApiAiJson<QueryResponse>.Serialize(queryResponse);
var deserializejson =ApiAiJson<QueryResponse>.Deserialize(stringjson);
if (deserializejson.Result.Action == "web.search")
{
JObject jsonob = JObject.Parse(stringjson);
string q = jsonob["parameters"]["q1"].ToString();
System.Console.WriteLine(q);
}
But string q returns "null".
Maybe the deserialisation is wrong. The value is embedded in parameters and not the root value. But I don't know how to get the root value of json.
Plus,here's the json response:
"result": {
"source": "agent",
"resolvedQuery": "search for apple",
"action": "web.search",
"actionIncomplete": false,
"parameters": {
"q1": "apple",
"q2": ""
},
Help!
Use below code:
q = jsonob["result"]["parameters"]["q1"].ToString();
I'm retrieving JSON which may vary in content items and want to find values associated with particular keys, e.g. in this case "geo_latitude" and "geo_longitude". For clarity, I'm only including those two items in this JSON sample. (It's typically much longer and in no particular order).
[
{
"id": 524616,
"key": "geo_latitude",
"value": "36.1069652"
},
{
"id": 524617,
"key": "geo_longitude",
"value": "-112.1129972"
}
]
This was the best I was able to come up with to parse the JSON. Is there a better way?
var metadataObj = JArray.Parse(postMetadataJsonStr);
var latContainer = metadataObj.Descendants()
.OfType<JObject>()
.Where(x => x["key"] != null &&
x["key"].Value<string>() == "geo_latitude").Select(y => y["value"]);
var latTokenJValue = latContainer.FirstOrDefault();
if (latTokenJValue == null) return;
var latitude = latTokenJValue.ToString();
I would convert your json to a dictionary
var metadataObj = JArray.Parse(postMetadataJsonStr);
var dict = metadataObj.ToDictionary(x => (string)x["key"], x => (double)x["value"]);
Console.WriteLine(dict["geo_latitude"]);