C# and json data parsing - c#

I have a problem on data parsing, I am using C# in Visual Studios and I need a parsing algorithm for my json file. This is the structure:
{
"objects": {
"minecraft/sounds/mob/stray/death2.ogg": {
"hash": "d48940aeab2d4068bd157e6810406c882503a813",
"size": 18817
},
"minecraft/sounds/mob/husk/step4.ogg": {
"hash": "70a1c99c314a134027988106a3b61b15389d5f2f",
"size": 9398
},
"minecraft/sounds/entity/rabbit/attack2.ogg": {
"hash": "4b90ff3a9b1486642bc0f15da0045d83a91df82e",
"size
I want to pull "minecraft/sounds/mob/stray/death2.ogg" and "hash" the data.
My C# code:
HttpWebRequest reqobje = WebRequest.Create(assetsurl) as HttpWebRequest;
using (HttpWebResponse response = reqobje.GetResponse() as HttpWebResponse)
{
StreamReader objejsonsr = new StreamReader(objectjson);
jsonVerisi = objejsonsr.ReadToEnd();
}
parser = JObject.Parse(jsonVerisi);
JToken job = parser["objects"];

Since you're using json.net, you can deserialize the string into any object you need. The sample below is an anonymous type with dictionary so you can use the dynamic keys that are coming back:
var result = JsonConvert.DeserializeAnonymousType(jsonVerisi, new { objects =
new Dictionary<string, Dictionary<string, string>>() });
var objects = result.objects; // key/value;
This is one way you can use it (maybe even to map to your own model instead of anonymous types to make it easier to work with):
var objects = result.objects
.Select(m => new
{
Path = m.Key,
Hash = m.Value["hash"],
Size = int.TryParse(m.Value["size"], out var value) ? value : 0,
}).ToList();
var path = objects[0].Path; // Get the path of the first object

Related

How to convert JSON Object to JSON Array in C# Restsharp (Exception- cannot convert newtonsoft.json.linq.jobject to newtonsoft.json.linq.array")

Below is my Requirement-
Actual JSON=
{
"page":2,
"per_page":6,
"total":12,
"total_pages":2
}
I want to make it as below-
[
{
"page":2,
"per_page":6,
"total":12,
"total_pages":2
}
]
It would be great help if someone can provide the best logic to do this in C# (RestSharp)
Basically you can store your json data inside the list.
var json = new
{
name = "john doe",
age = 20
};
var list = new List<dynamic>();
list.Add(json);
Later on, when you serialize your list. It will look like this:
[{"name":"john doe","age":20}]
Hopefully it helps.
Create an empty array and then push json object into that array.
Example :
var obj = { "name":"test", "email":"test#test.com" };
var list = [];
list.push(obj);
Result :
list = [{ "name":"test", "email":"test#test.com" }];
You can use below code, this is working one.
var obj = new { name = "test", email = "test#test.com" };
var list = new List<dynamic>();
list.Add(obj);

How to get property value from .net dynamic array object

I've got a json file containing
{
"Accounts": null,
"AccountTypes": null,
"Actions": null,
"Photos": [
{
"Instance": "...",
"Key": "..."
},
....
]
}
Now I want to get all the Instance properties from the Photo objects. I've got the following code:
var photos = new List<Photo>();
string json = File.ReadAllText(file);
dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json, typeof(object));
var jsonPhotos = jsonObj.Photos as IEnumerable<dynamic>;
var instances = jsonPhotos.Select(x => x.Instance);
foreach (var instance in instances)
photos.Add(new Photo
{
Document = Convert.FromBase64String(instance)
});
However, jsonPhotos.Select(x => x.Instance); isn't returning anything...
I am able to get things working by using
var instances = new List<string>();
foreach (var photo in jsonPhotos)
instances.Add(photo.Instance.Value);
But can I solve this in a LINQ way?
Why just don't use Json.Linq for that? Parse JSON to JObject instance, then map every token from Photos array to Photo instance (I've omitted Convert.FromBase64String because OP sample doesn't have a valid base64 data, but converting Instance value can be easily added)
var json = JObject.Parse(jsonString);
var photos = json["Photos"]
.Select(token => new Photo
{
Document = token["Instance"]?.Value<string>()
})
.ToList();
The .Select(x => x.Instance) indeed returns ... on .NET Core 3.1. Can you verify that the contents of the json variable are actually what you expect?
Specifically
jsonPhotos.Select(x => x.Instance);
works as expected, while
jsonPhotos.Select(x => x.SomeNonExistingProperty);
enumerates nothing / empty values.
For example, this code prints Instance A, then Instance B, then nothing twice:
var json = #"
{
""Photos"": [
{
""Instance"": ""Instance A"",
""Key"": ""...""
},
{
""Instance"": ""Instance B"",
""Key"": ""...""
}]
}";
var jsonObj = JsonConvert.DeserializeObject<dynamic>(json);
var jsonPhotos = jsonObj.Photos as IEnumerable<dynamic>;
var instances = jsonPhotos.Select(x => x.Instance);
foreach (var instance in instances)
{
Console.WriteLine(instance);
}
// In contrast, this one will print empty lines.
instances = jsonPhotos.Select(x => x.SomeNonExistingProperty);
foreach (string instance in instances)
{
Console.WriteLine(instance);
}
I took the liberty to change the deserialization to dynamic directly, but it also works with the original code from the question.

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)

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.

JSON trouble; deserialising to a datatable

I am trying to load JSON into a SQL database using JSON.net.
I've had no issues with other JSON responses however the following format doesn't seem to deserialise correctly.
{"Report":["2012m01d01","2012m01d02","2012w01","2012m01","2012m01d03","2012m01d04","2012m01d05","2012m01d06","2012m01d07","2012m01d08"],
"Realtime":null}
Could anybody provide some insight into why this would be? I'm using the following code to deserialise with.
public void Deserialize(String jsonText, ref DataTable dt)
{
JsonSerializer json = new JsonSerializer();
json.NullValueHandling = NullValueHandling.Ignore;
json.ObjectCreationHandling = ObjectCreationHandling.Replace;
json.MissingMemberHandling = MissingMemberHandling.Ignore;
json.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
StringReader sr = new StringReader(jsonText);
JsonTextReader reader = new JsonTextReader(sr);
dt = (DataTable)json.Deserialize(reader, typeof(DataTable));
reader.Close();
}
Any ideas on what the best approach to solving this would be? This works fine with other JSON responses!
Thanks in advance
JSON is able to hold hirarchial information, that does not translate into a single datatable, but rather into several using a dataset and table relationships.
I put your json in http://jsonlint.com validator and formatter
you say this deserializes with no problems
{
"accountID": 1,
"profileID": null,
"name": "Pages",
"ID": "18d039ae0360",
"language": n‌​ull,
"type": null,
"Category": null,
"IsHierarchy": false,
"IntervalsEnabled": true,
"IsRe‌​altimeCompatible": true,
"properties": null
}
this is a single object
but this doesn't deserialize properly.
{
"Report": [
"2012m01d01",
"2012m01d02",
"2012w01",
"2012m01",
"2012m01d03",
"2012m01d04",
"2012m01d05",
"2012m01d06",
"2012m01d07",
"2012m01d08"
],
"Realtime": null
}
Actually your problem is data handling not serializion
the first is a single object and can be deserialized into a DataTable
and the other is an object that holds a reference to a list of report objects.
therefore you need to manually write a converter from your object to two dataTables
this code works, and i'm sure you can create a conversion function for your two tables
var settings = new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Error,
NullValueHandling = NullValueHandling.Include
};
JsonSerializer json = JsonSerializer.Create(settings);
json.Error += (x, y) =>
{
var s = y.ErrorContext;
var t = y.CurrentObject;
};
StringReader sr = new StringReader(jsonString);
JsonTextReader reader = new JsonTextReader(sr);
var o = json.Deserialize<ClsReport>(reader);
string sf = o.ReportItems[2];
Hope this helps

Categories

Resources