I am trying the convert my json string into dictionary but could not successful.
{
"healths": [
{
"serviceName": "UserMgt",
"subService": [
{
"subServiceName": "Base",
"status": 10
},
{
"subServiceName": "Url",
"description": "Url is bad",
"status": 10
},
{
"subServiceName": "Configuration",
"status": 2
}
]
},
{
"serviceName": "ConfigurationMgt",
"subService": [
{
"subServiceName": "url",
"description": "urlis OK!",
"status": 2
},
{
"subServiceName": "Configuration Db",
"status": 2
}
]
}
}...and so son
So, as you see we have a service name, and based on that we have subserviceName then again service name and subservicename.Basiclly i want to convert this into dictionary as a key-value pair so that based on the key(service) we have values subservice(again a key value pair).
I tried many things but does not get a proper result.
like for example using newtonsoft nuget.
JObject jsonObj = JObject.Parse(formattedJson);
Dictionary<string, object> dictObj = jsonObj.ToObject<Dictionary<string, object>>();
foreach(var kv in dictObj)
{
Console.WriteLine(kv.Key + "::::" + kv.Value);
}
In this scenario I am getting output like key as a healths and every thing as a value.
Can anyone please help me regarding this.The Json and c# is new for me.
Thanks In Advance.
Assuming that you are guaranteed to have the described structure, you can deserialize to JObject and use LINQ's ToDictionary to process it:
var dict = JsonConvert.DeserializeObject<JObject>(json)["healths"]
.ToDictionary(
s => s["serviceName"].ToString(),
s => s["subService"]
.ToDictionary(ss => ss["subServiceName"].ToString(), ss => ss["status"].ToString()));
Where you can change ss => ss["status"].ToString() to select what is actually needed as subService value.
Related
I have a JSON response here,
{
"Items": [
{
"Key": {
"timestamp": "2022-11-06T20",
"value": 100.80
}
},
{
"Key": {
"timestamp": "2022-11-07T08",
"value": 100.90
}
}
]
}
That I would like to reformat to this:
{
"Key": [
{
"timestamp": "2019-01-08T20",
"value": 12.44
},
{
"timestamp": "2018-12-12 16:23:00",
"value": 12.45
}
]
}
For all responses, the Key must only be on the top once followed by an array of timestamps and values, and remove the Items parent value completely. I have tried doing this and messing around with the implementation, but I keep receiving multiple different errors. Is this the correct idea to do it or is there a better way to implement this?
JObject obj = JObject.Parse(jsonOutput);
JObject newObj = new JObject();
new JProperty("KEY", new JArray(
.Children<JProperty>()
.Select(j => new JObject(
new JProperty("timestamp", j.Value["timestamp"]),
new JProperty("value", j.Value["value"])
)
)
)
);
jsonOutput = newObj.ToString();
What is the correct way to implement this idea? Thanks!
This can be done very easily by combining
SelectTokens() with a JSONPath wildcard operator for the Items[*] array to select all required JSON objects.
Serialization of an anonymous type object to create the required output structure.
Thus:
var query = obj.SelectTokens("Items[*].Key");
jsonOutput = JsonConvert.SerializeObject(new { Key = query }, Formatting.Indented);
Demo fiddle here.
you can fixed it in one line
jsonOutput = new JObject {new JProperty("Key", ((JArray)JObject.Parse(jsonOutput)
["Items"]).Select(s => s["Key"]))}.ToString();
I have this result
{
"StatusCode": "200",
"Description": "Success",
"Data": [
{
"Language_Key": "btn_select_country",
"En_Val": "SELECT COUNTRY",
"Ar_Val": "اختر الدولة"
},
{
"Language_Key": "btn_continue",
"En_Val": "CONTINUE",
"Ar_Val": "استمرار"
}
]
}
I would like to achieve below result.
{
"StatusCode":"200",
"Description":"Success",
"Data":{
"btn_select_country":{
"En_Val":"SELECT COUNTRY",
"Ar_Val":"اختر الدولة"
},
"btn_continue":{
"En_Val":"CONTINUE",
"Ar_Val":"استمرار"
}
}
}
I want Language_Key to replace with column name and with 2 child nodes as EN and AR below is my code
Any hint is appreciated. Thanks
you serialize a dictionary where the key is your Language_Key:
Dictionary<string, Translation> dict = countryObj
.ToDictionary(o => o.Language_Key, o => new Translation { Ar_Val = o.Ar_Val, En_Val = o.En_Val});
rs.Data = dict;
json = new JavScriptSerializer().Serialize(rs);
You can use JsonProperty Attribute to rename properties after they get serialize.
https://www.newtonsoft.com/json/help/html/JsonPropertyName.htm
I am recieving this JSON response from an API:
{
"type": "link",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "0000000000000",
"errors": {
"inputNumber": [
"Must be 5 characters."
],
"inputWord": [
"Required."
]
}
}
I am using a profile with AutoMapper to map the response to a model. Here is the code where I'm trying to map the JSON errors property to a Dictionary<string, List<string>> property in my response model:
// Map for Errors property
.AfterMap((src, dest) =>
{
dest.Errors = new Dictionary<string, List<string>>();
var jsonErrorDict = src.SelectTokens("errors").Children();
foreach (var token in jsonErrorDict)
{
// Not working right: Token contains both key and value
var key = token;
var value = new List<string>();
if (token.HasValues)
{
var jsonErrorKeyValues = token.Children();
foreach (JToken innerToken in jsonErrorKeyValues)
{
value.Add(innerToken.ToString());
}
dest.Errors.Add(key.ToString(), value);
}
}
But the token variable contains both the key ("inputNumber" for example) as well as the value ("Must be 5 characters"), so when the mapping is done it looks like this:
"errors": {
"\"inputNumber\": [\r\n \"Must be 5 characters.\"\r\n]": [
"[\r\n \"Must be 5 characters\"\r\n]"
],
"\"inputWord\": [\r\n \"Required\"\r\n]": [
"[\r\n \"Required.\"\r\n]"
}
Im just testing it and getting the response from an escaped string so ignore the escape symbols like \r.
How do I get only the key name?
EDIT:
I added this to the key variable:
var key = token.ToString().Split(':');
And then when I'm adding it to the dest.Errors dictionary I do this:
dest.Errors.Add(key[0], value);
Doesn't feel like the best solution though so alternative solutions are more than welcome.
I can't figure out how to use JToken to get the "Total Income" amount of "325.00".
I have tried quite a few different lines of code but seem to be missing something obvious.
{
"Rows": {
"Row": [
{
"Rows": {
},
"type": "Section",
"group": "Income",
"Summary": {
"ColData": [
{
"value": "Total Income"
},
{
"value": "325.00"
}
]
}
},
{
}
]
}
}
For the specific JSON sample that you have given in your question, you can extract the 325.00 value using SelectToken like this:
var obj = JObject.Parse(json);
var amount = (string)obj.SelectToken("Rows.Row[0].Summary.ColData[1].value");
Fiddle: https://dotnetfiddle.net/WRMAVu
If you want to extract both the label and the amount you can use SelectTokens instead with a wildcard for the ColData index:
var obj = JObject.Parse(json);
var values = obj.SelectTokens("Rows.Row[0].Summary.ColData[*].value")
.Select(t => (string)t)
.ToArray();
Fiddle: https://dotnetfiddle.net/DHZhS2
I have a valid JSON object that contains multiple "en-US" keys, which I'm trying select. For that purpose I use the JsonPath
"$..en-US"
which is given to the SelectTokens procedure implemented by the Json.NET. It's a JSON framework for .NET . Everything is working fine and well as long as my JSON doesn't contain any empty array.
Here's an example:
var myJsonPath = "$..en-US";
var myJson =
#"{
'controls': [
{
'messages': {
'addSuggestion': {
'en-US': 'Add'
}
}
},
{
'header': {
'controls': []
},
'controls': [
{
'controls': [
{
'defaultCaption': {
'en-US': 'Sort by'
},
'sortOptions': [
{
'label': {
'en-US': 'Name'
}
}
]
}
]
}
]
}
]
}";
var jToken = JObject.Parse(myJson);
var tokens = jToken.SelectTokens(myJsonPath);
Here, the tokens variable will contain just one element! That will be the "en-US" occurence BEFORE the empty array in the 'controls' of the 'header' object. However, when I just leave this 'header' object out:
var myJson =
#"{
'controls': [
{
'messages': {
'addSuggestion': {
'en-US': 'Add'
}
}
},
{
'controls': [
{
'controls': [
{
'defaultCaption': {
'en-US': 'Sort by'
},
'sortOptions': [
{
'label': {
'en-US': 'Name'
}
}
]
}
]
}
]
}
]
}";
I will get all the 3 occurencies of the "en-US" as expected. Btw, if I validate my JsonPath on the first JSON object (i.e. which contains an empty array) in an online tool, then as expected, I get all the three "en-US" cases. This diverges from what I'm getting from the Json.NET. I'm wondering whether it's a bug or do I have to handle this case manually somehow?
This is a bug that has been fixed. Upgrade to the latest version of Json.NET.
If you're in the same situation as me where you're a bit stuck with respect to updating your version of Json.NET, you can work around the issue by doing something along the lines of this:
IEnumerable<JValue> vals = jToken
.Desecendants()
.Where(w => w is JProperty && w.Name=="en-US")
.Select(s => s.Value);
Hope that helps! The vals array will contain the same tokens you would have gotten using the selector you were trying to use before.