error of reading Json string in C# by JsonConvert - c#

I need to read data from a Json string in C#.
The Json string is like:
{
"data_level":{
"performance":{
"#value":"1000",
"#size":"10",
},
"points":{
"#type":"profit",
"tier":{
"#below":"80",
"#above":"100"
},
"kids":[
{
"#kid":"150"
},
{
"#kid":"200"
}
]
}
}
My C# code:
var my_dic = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json_string);
var my_data = my_dic["data_level"]
string v = my_data["performance"]["#size"];
For "kids", I have two child "kid" have the same name but differne value. How to get all of them instead of only the one last read ?
Any help would be appreciated.

You should leave out the last [0] .

For the updated question:
my_children = my_dic["points"]["kids"];
foreach (KeyValuePair<string, int> pair in my_children)
{
Console.WriteLine(pair.Key, pair.Value["#kid"]);
}
This should work...

Related

Query JArray using SelectTokens and a contains regex

I am trying to write a method that will take the following JSON structure below and return the path proerty for all of these where path contains a string. So in this case, if I called GetPath(json, "User1") I would like to get ["User1\path1", "User1\path2"]
[
{
"id":90BCV,
"name":"Path 1",
"path":"User1\\path 1"
},
{
"id":90BC,
"name":"Path 2",
"path":"User1\\path 2"
},
{
"id":91AB,
"name":"Path 3",
"path":"User2\\path 3"
}
]
public static List<string> GetPath(string json, string key)
{
JArray reader = JArray.Parse(json);
List<JToken> paths = reader.SelectTokens("$.[?(#.path=~#'" + key + "')]").ToList();
List<string> returnList = new List<string>();
foreach (JToken path in paths)
{
returnList.Add((string)path["path"]);
}
return returnList;
}
I have tried multiple different regex approaches but I just can not seem to get this query right. Most of the times I just end up getting an empty list or an invalid regex error.
That works
static string json = #"
[
{
""id"":""90BCV"",
""name"":""Path 1"",
""path"":""User1\\path 1""
},
{
""id"":""90BC"",
""name"":""Path 2"",
""path"":""User1path 2""
},
{
""id"":""91AB"",
""name"":""Path 3"",
""path"":""User2\\path 3""
}
]
";
static void Main(string[] args)
{
string key = "User2\\\\path 3";
JArray reader = JArray.Parse(json);
List<JToken> paths = reader.SelectTokens("$.[?(#.path=='" + key + "')]").ToList();
}
few thing are there
- ==, not just =, cause JPath uses in-code compiler, so you follow C# convension.
- for the same reason, it you need \\ to represent \
By the way, if you really want to do Regular Expression way, you almost had it right:
List<JToken> paths = reader.SelectTokens("$.[?(#.path=~/^" + key + "$/)]").ToList();
I don't know why you would want to go with this approach. I would rather use .ToString() and then use .Contains inside the foreach loop.
JArray reader = JArray.Parse(json);
List<string> returnList = new List<string>();
foreach(var token in reader){
string path = token["path"].ToString();
if(path.Contains(key)){
returnList.Add(path);
}
}

Why can I not parse Neo4jClient's query result (type string) into a Dictionary<string, string> using JsonConvert in C#

I am trying to parse Neo4jClient's query result of paths (of type string) using JsonConvert.
I was able to parse the query result for nodes using this method:
var _gClient = new GraphClient(new Uri("http://localhost:7474/db/data"));
_gClient.Connect();
var result = _gClient.Cypher
.Match("(n)")
.Return(n => n.As<string>())
.Results.ToList();
result.ForEach(n =>
{
var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(n);
Console.WriteLine("Keys: " + String.Join(",", dict.Keys));
Console.WriteLine("Values: " + String.Join(",", dict.Values));
});
However, when I tried to do the same with the query result of paths, JsonConvert's DeserializeObject method can't do the same thing:
var _gClient = new GraphClient(new Uri("http://localhost:7474/db/data"));
_gClient.Connect();
var result = _gClient.Cypher
.Match("p=(a)-[:ACTED_IN]->(m:Movie {title:'The Matrix'})")
.Return(p => new
{
Nodes = Return.As<IEnumerable<string>>("EXTRACT(p in nodes(p) | p)"),
Relationships = Return.As<IEnumerable<string>>("EXTRACT(p in relationships(p) | p)")
})
.Results.ToList();
foreach (var n in result)
{
foreach (var s in n.Nodes)
{
JsonConvert.DeserializeObject<Dictionary<string, string>>(s);
}
}
The error was Unexpected character encountered while parsing value: {. Path 'extensions', line 2, position 17.
This is part of the string to be parsed:
{
"extensions": {},
"metadata": {
"id": 8,
"labels": [
"Person"
]
},
Does that mean Json can't deserialize empty braces? If so is there any other way I can parse this huge structure out?
The problem is that you're trying to deserialize into a Dictionary<string,string> but your JSON isn't a Dictionary<string,string> the error about the unexpected { is because for it to be a Dictionary<string,string> the JSON would look like:
{
"Key1" : "Value1",
"Key2" : "Value2"
}
The { on both extensions and metadata imply that there is an object there, not just a string. To that end you can deserialize it using something like:
JsonConvert.DeserializeObject<Dictionary<string, object>>(s)
But if you want to access the properties, you may as well do:
JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(s)

Make dynamic dictionary from json file

I have json file like this:
{
"fields": {
"customfield_10008": {
"value": "c1"
},
"customfield_10009": {
"value": "c2"
}
...
}
}
and I would like to create dictionary in c# like:
key: value
"customfield_10008":"c1"
"customfield_10009":"c2"
How I can achive this? I load json in this way,
dynamic json = JsonConvert.DeserializeObject(File.ReadAllText("data.json");
and don't know how to create dict like above
A little bit linq tricks can help you
var dict = JObject.Parse(File.ReadAllText("data.json"))["fields"]
.Cast<JProperty>()
.ToDictionary(x => x.Name, x => (string)x.Value["value"]);
Come through the values and collect them:
var result = new Dictionary<string, string>();
foreach (var field in obj.fields)
{
result.Add(field.Name, Convert.ToString(field.Value.value));
}
If you have json which do not have type in compile time, you can use dynamic type at that time.
I would parse above json using dynamic type and generate dictionary with parsed value :
var dicValues = new Dictionary<string,string>(); // this dictionary contains key value pair result
dynamic res = JsonConvert.DeserializeObject<dynamic>(File.ReadAllText("data.json");
dynamic availableFields = res["fields"];
if (availableFields != null)
{
foreach (var field in availableFields)
dicValues.Add(field.Name, field.Value["value"].Value);
}

Complex json tree parsing

So I am given a json tree like the one below and I really just need to get the persons first and last names from here but I am having problems parsing the data.
{
"results":[
{
"id":{
"key":"Phone.81dd6fef-a2e2-4b08-cfe3-bc7128b43786.Durable",
"url":"https://proapi.whitepages.com/2.1/entity/Phone.81dd6fef-a2e2-4b08-cfe3-bc7128b43786.Durable.json?api_key=",
"type":"Phone",
"uuid":"81dd6fef-a2e2-4b08-cfe3-bc7128b43786",
"durability":"Durable"
},
"line_type":"Landline",
"belongs_to":[
{
"id":{
"key":"Person.1ffee2ef-cc88-4a1e-87b0-05349571b801.Durable",
"url":"https://proapi.whitepages.com/2.1/entity/Person.1ffee2ef-cc88-4a1e-87b0-05349571b801.Durable.json?api_key=",
"type":"Person",
"uuid":"1ffee2ef-cc88-4a1e-87b0-05349571b801",
"durability":"Durable"
},
"type":"Full",
"names":[
{
"salutation":null,
"first_name":"fred",
"middle_name":null,
"last_name":"jones",
"suffix":null,
"valid_for":null
}
],
"age_range":null,
"gender":null,
"locations":[
{
"id":{
"key":"Location.bd4721f0-ba97-4ade-aac1-ed1f16be57ed.Durable",
"url":"https://proapi.whitepages.com/2.1/entity/Location.bd4721f0-ba97-4ade-aac1-ed1f16be57ed.Durable.json?api_key=",
"type":"Location",
"uuid":"bd4721f0-ba97-4ade-aac1-ed1f16be57ed",
"durability":"Durable"
},
"type":"Address",
"valid_for":{
"start":{
"year":2011,
"month":7,
"day":5
},
"stop":null
},
"legal_entities_at":null,
"city":"",
"postal_code":"",
"zip4":null,
"state_code":"",
"country_code":"",
"address":"",
"house":"10",
"street_name":"",
"street_type":"Ave",
"pre_dir":null,
"post_dir":null,
"apt_number":null,
"apt_type":null,
"box_number":null,
"is_receiving_mail":false,
"not_receiving_mail_reason":null,
"usage":null,
"delivery_point":null,
"box_type":null,
"address_type":null,
"lat_long":{
"latitude":,
"longitude",
"accuracy":"Street"
},
"is_deliverable":true,
"standard_address_line1":"",
"standard_address_line2":"",
"standard_address_location":"",
"is_historical":false,
"contact_type":"Home",
"contact_creation_date":1361177323
}
],
The code I have been using so far is:
string url = String.Format("https://proapi.whitepages.com/2.1/phone.json?api_key={0}&phone_number={1}", WhitePagesConstants.ApiKey, number);
using (WebClient webClient = new System.Net.WebClient())
{
WebClient n = new WebClient();
n.Encoding = System.Text.Encoding.UTF8;
var json = n.DownloadString(url);
Dictionary<string, Object> formattedjson = JsonConvert.DeserializeObject<Dictionary<string, Object>>(json);
}
I have been on this for too long and must finish it shortly so I ask please help me traverse this tree. I have never worked with json before and am quite lost on how to do this. The exact info I need is under "belongs_to" -> "names" -> first and last. I've changed some names to protect the innocent.
If all you need is to extract several properties, you can just navigate the path:
dynamic o = JsonConvert.DeserializeObject(json);
Console.WriteLine(o.results[0].belongs_to[0].names[0].first_name);
Console.WriteLine(o.results[0].belongs_to[0].names[0].last_name);
Or, if you prefer string dictionaries over dynamic objects:
JObject j = JsonConvert.DeserializeObject<JObject>(json);
Console.WriteLine(j["results"][0]["belongs_to"][0]["names"][0]["first_name"]);
Console.WriteLine(j["results"][0]["belongs_to"][0]["names"][0]["last_name"]);
P.S. Your JSON is broken. It would have been easier for me to test code if you provided a correct example.

Bind json variable data to the dropdownlist from jquery

In my asp.net web page, I have prepared the JSon string with the help of JavaScriptSerializer class.
And i have spit the Json string in to the HTML markup with the help of RegisterStartupScript method and it looks like this,
C#.net code to prepare the json string,
System.Web.Script.Serialization.JavaScriptSerializer jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
List<Dictionary<string, string>> glAccts = new List<Dictionary<string, string>>();
Dictionary<string, string> row;
foreach (DataRow dr in _dtProfitCenterRawData.Rows)
{
row = new Dictionary<string, string>();
row.Add(dr[0].ToString(), dr[1].ToString());
glAccts.Add(row);
}
string jsonObj = jsSerializer.Serialize(glAccts);
string script = "var glList = " + jsonObj + ";";
ClientScriptManager cs = Page.ClientScript;
cs.RegisterStartupScript(Page.GetType(), "JSONObj", script, true);
The glList variable on the client html looks like this,
var glList = [
{ "1110005": "1110005 - X1" },
{ "1110008": "1110008 - X2" },
{ "1110011": "1110011 - X3" },
{ "1110020": "1110020 - X4" }
];
I want to bind this json string to dropdownlist control. Please suggest how to perform that? I tried to perform the following action to view the data inside the object, but it does not give me the real values. It gives [object] in the alert methods.
Please suggest the fix to the problem..
$.each(glList, function (val, text) {
//$('#mySelect').append(new Option(text, val));
alert(text); alert(val);
});
Try this here. If you itereate through glList you get the objects but not their properties.
function jsonTest() {
$.each(glList, function(index, obj) {
($.each(obj, function (key, value) {
$('#mySelect').append(new Option(key, value));
}));
});
}
Use JSON.Net instead JavaScriptSerializer to serialize a Dictionnary.
Or you can try to cast to object before serialize
jsSerializer.Serialize((object)glAccts)
try
var glList = [
{ 1110005: "1110005 - X1" },
{ 1110008: "1110008 - X2" },
{ 1110011: "1110011 - X3" },
{ 1110020: "1110020 - X4" }
];

Categories

Resources