c# Json.net deserializing List<Dictionary<string,object>> - c#

What is the proper way to deserialize this JSON string? It is simply an array of dictionaries where each dict has a "title" and "children" where children is another array of dicts.
I am using this as a TreeView item source, but the treeview only displays the Title1 > Child1 because I assume something is wrong with the deserializing I'm doing. I also try to print out Child1's first child but can't figure out how to do it. The code below has an invalid cast exception.
s = #"[{""title"":""Title1"",""children"":[{""title"":""Child1"",""children"":[{""title"":""grandchild1"",""children"":[{""title"":""Huh""}]}] }] }]";
List<Dictionary<string, object>> marr = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(s);
mTreeView.ItemsSource = marr;
List<Dictionary<string,object>> cs = (List<Dictionary<string,object>>)marr[0]["children"];
Debug.WriteLine(cs[0]["title"]);

Looks to me like you have the following:
class MyObject
{
public string title { get; set; }
public List<MyObject> children { get; set; }
}
var deserialized = JsonConvert.DeserializeObject<List<MyObject>>(s);
And no, there's no dictionary here, because:
Try as I might, I don't see a "dictionary" here so much as a recursive list of the object above, and
This is the actual definition of the object your want out anyway, so you can take advantage of all the benefits of having a real type, rather than just a dictionary of strings.
Note to address your comments: If the JSON string changes, it will not break your code; extraneous properties will be ignored and missing properties will correctly get set to null.

https://codetitans.codeplex.com/
codetitans JSON supports correct parsing of JSON into array/dict of primitives as follows:
JSonReader jr = new JSonReader();
IJSonObject json = jr.ReadAsJSonObject(s);
Debug.WriteLine(json[0]["children"][0]["title"]);
As far as I can tell it is the only C# library that does.

It looks like you can do this with JSON.NET out of box currently
var #object = JsonConvert.DeserializeObject(s)
var slightlyMoreUsefulObject = (JArray)#object;
var actualObject = slightlyMoreUsefulObject[0]
var topLevelTitle = actualObject["title"]
var children = actualObject["children"]
var firstChild = children[0]
var firstChildTitle = firstChild["title"]

Related

Need to get variable name and its data from json file C#

Example of Json:
{
"typeOfDriver": "selenium",
"goToURL": "url",
}
Basically I need a way to gather the first variable name "typeOfDriver", with the code I'm using right now I just get the data from the element.
Code:
dynamic loadConfig = JsonConvert.DeserializeObject(File.ReadAllText(path + "/" + response));
string typeOfDriver = loadConfig["typeOfDriver"];
Thanks!
Edit: Explained better, I need to know the first line variable name, for example this time is typeOfDriver, another time will be another so I need to know it.
I'd highly recommend making a class to represent the data coming from the JSON file. If the data is dynamic, deserializing to a Dictionary might make the most sense. If you need to traverse the JSON hierarchy, you might want to deserialize to JObject. Anything that's not defined explicitly with Newtonsoft.Json will come back as JObject, so using dynamic isn't really necessary.
You can use JObject for that, parse your JSON and get the name and value from the first property
var json = JObject.Parse(File.ReadAllText(path + "/" + response));
var property = json.Properties().FirstOrDefault();
var name = property.Name; //returns "typeOfDriver" string
var value = property.Value.ToString();
With your current code and deserialize to dynamic it can be the similar
IEnumerable<JProperty> properties = loadConfig.Properties();
var name = properties.FirstOrDefault()?.Name; //returns "typeOfDriver" string
To iterate all properties names you can just go through them in a foreach loop
foreach (var property in loadConfig.Properties())
{
var name = property.Name;
}
Sounds like something you should be doing type-safe-ly. Something like this (don't forget to take using NewtonSoft.Json;):
public class InfoDto {
public string typeOfDriver {get; set;}
public string url {get; set;}
}
// get the string any way you want and then
InfoDto myObject = JsonConvert.DeserializeObject<InfoDto>(someString);
// use myObject.typeOfDriver any way you want ...

Get Key Name from nested json object

I am new to C# and JSON and need some help in getting the Key name(s) in a list of a nested JSON object. The keys are dynamic so I won't necessarily know the keys.
sample code I've tried.
```
protected void test()
{
var mystring = #"{
""zone1"": {
""sites"": {
""site1"": {
""to"": ""email1"",
""subject"": ""subjecttxt"",
""link"": ""somesite""
},
""site2"": {
""to"": ""email1"",
""subject"": ""subject"",
""link"": ""somesite""
}
},
""zone2"": {
""to"": ""email1"",
""subject"": ""subject"",
""link"": ""somelink""
}}";
var rss = JObject.Parse(mystring);
foreach (var section in rss)
{
Console.Write(section.Key);
IList<JToken> result = rss["zone1"]["sites"].Children().ToList();
var zone = section.Key;
var site = rss[zone]["sites"];
foreach (var subsite in rss["zone1"]["sites"])
{
var subs = subsite.Parent.ToString();
// some other code
}
}
}
```
Looking for a result:
site1,
site2,
...
I can get the children as IList but looking for something similar to "section.Key" as noted above.
Thank you for your help.
I believe what you are looking for is to get the properties of the sites. Since accessing the rss["zone1"]["sites"] returns a JToken, you will need to convert that to JObject and then use Properties() method to get the data you need.
var sites = ((JObject)rss["zone1"]["sites"]).Properties();
Then you can simply iterate over the IEnumerable<Jproperty> to get the Name of the property or whatever else you need from under it.
To get the section.Key for the sites, you can use the following code.
foreach(var site in (JObject)rss["zone1"]["sites"]) {
Console.WriteLine(site.Key);
}
Output:
site1
site2
Your first call to JObject.Parse already does all the work of converting a string into a structured JSON object. The currently-accepted answer redoes some of this work by (1) turning a structured JSON object back into a string, and then (2) re-parsing it with JObject.Parse. There is a simpler way.
Instead, you can cast the value stored at rss["zone1"]["sites"] into a JObject. (The expression rss["zone1"]["sites"] has type JToken, which is a parent class of JObject, but in this case we happen to know that rss["zone1"]["sites"] is always JSON object, i.e. a collection of key-value pairs. Therefore, this cast is safe to perform.)
This is what the code might look like:
var sites = (JObject) rss["zone1"]["sites"];
foreach (var site in sites)
{
Console.WriteLine(site.Key);
}

Easily working on a json object

I'm deserializing (or parsing) a json string to a c# object (using Json.NET) and getting a JObject. I want to iterate all the properties with the key "bla", in the same way iterating all xml elements that named "bla" with XElement.Elements("bla").
If it's not possible, I would like to deserialize my json string into a c# object, and work dynamically and recursively on my deserialized json object (my json string can have lists / arrays that can have objects of 2 types.
In the end after editing my object (changing values and removing or adding properties) I need to serialize my object back to a json string.
Which is the best and easiest way to use json serializing and deserializing?
my Json looks like this:
{"Families":{"Family":[{"propA":"dhsj", "propB":"dhdisb"}, {"propA":"krbsbs", "propC":"ksndbd", "propD":"odndns", "Families":{"Family":[....]}}, {"propA":"dhsj", "propB":[{"propA":"dhsj", "propB":"dhdisb"}, {"propA":"krbsbs", "propC":"ksndbd", "propD":"odndns", "Families":{"Family":[....]}}, {"propA":"dhsj", "propB":"fghfgh"}]}]}
in conclusion, the json value is a json object that it's value is a list/array, the list/array can contain 2 "types" of objects, and one of these types also has a property which it's value is a json object that it's value is a list/array, and it goes like this recursively. sometimes the value of one of the props of the type that doesn't have a property which it's value is a json object that it's value is a list/array, can be a list/array itself, that can contain only 1 type of the two mentioned.
If you don't need a strongly-typed object, you can deserialize to a dictionary:
Dictionary<string, object> myObject = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
And then just use it as a dictionary:
myObject["Property"] = value;
Or
foreach(var propertyKey in myObject.Keys)
{
// do something with each property
Console.WriteLine($"{propertyKey} = {myObject[propertyKey]}");
}
Here's a fiddle
You can serialize it back after you are done
My json looks more like this:
{"Familys":{"Family":[{"propA":"dhsj", "propB":"dhdisb"}, {"propA":"krbsbs", "propC":"ksndbd", "propD":"odndns", "Families":{"Family":[....]}}]}
For JSON like this:
var json = #"{
""Families"":{
""Family"":[
{
""propA"":""Top""
},
{
""propA"":""Top.Lower"",
""Families"":{
""Family"":[
{
""propB"":""propB value""
},
{
""propA"":""Top.Lower.EvenLower"",
""Families"":{
""Family"":[
{
""propA"":""Top.Lower.EvenLower.EvenLower""
}
]
}
}
]
}
}
]
}
}";
Do something like this:
//calling code makes use of "dynamic" to make things clean and readable.
dynamic parsedJson = JsonConvert.DeserializeObject(json);
var allPropAValues = GetPropAValues(parsedJson);
//**** NOTE: this has our extra property ****
var jsonWithExtraStuffProperty = JsonConvert.SerializeObject(parsedJson);
//recursive function that reads AND writes properties
public static List<string> GetPropAValues(dynamic obj)
{
var propAValues = new List<string>();
//**** NOTE: the use of an added property ****
obj.ExtraStuff = new Random().Next();
//if we have a propA value, get it.
if (obj.propA != null)
propAValues.Add(obj.propA.Value);
//iterate through families if there are any. your JSON had Families.Family.
if (obj.Families != null)
foreach (dynamic family in obj.Families.Family)
propAValues.AddRange(GetPropAValues(family));
return propAValues;
}

How to create a json string where a property contains a dot (period)?

I'm trying to send an HttpRequest that takes a JSON object like this:
{
"some.setting.withperiods":"myvalue"
}
I've been creating anonymous objects for my other requests, but I can't do that with this one since the name contains a dot.
I know I can create a class and specify the [DataMember(Name="some.setting.withperiods")] attribute, but there must be a more lightweight solution.
There is no "easy" way to achieve this because the . in C# is reserved.
However, you could achieve something pretty close by using a dictionary and collection initializer. It's still somewhat isolated, and doesn't require you to create a custom class.
var obj = new Dictionary<string, object>
{
{ "some.setting.withperiods", "myvalue" }
};
var json = JsonConvert.SerializeObject(obj);
//{"some.setting.withperiods":"myvalue"}
You can use "JsonProperty" attribute for the same For example
[JsonProperty(".Name")]
public string Name { get; set; }
On top of this I want to add how to retrieve the data from the json where it has name property starting with special character as in Web API 2.0 token has ".issued".
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
var jsonRespons="json response from the web api";
var issue= JObject.Parse(jsonResponse).GetValue(".issued");
if you do it from in javascript, you can easily go back and forth, as shown with:
var obj = {
"some.setting.withdots":"myvalue"
};
var json = JSON.stringify(obj);
console.log(json);
var str = JSON.parse(json);
console.log(str);
have you tried putting it into a serialized string and sending that, then deserializing on the client-side?
you could do something like
var myAnnon = new
{
WithPeriod = "value"
};
var j = JsonConvert.SerializeObject(myAnnon);
j = j.Replace("WithPeriod", "some.setting.withdots");
You can use a JObject (part of Json.Net's LINQ-to-JSON API) to create the JSON in question:
string json = new JObject(new JProperty("some.setting.withperiods", "myvalue")).ToString();
Fiddle: https://dotnetfiddle.net/bhgTta
You could try prefixing your member names with a # to allow use of literals, but the way to do it is using [DataMember] as you have already mentioned in your question.

JavaScriptSerializer: Serialize a list + a string into JSON

I want to use JavaScriptSerializer to send a package of JSON data that contains both a list of objects as well as a string, identified like ChatLogPath. As far as I can tell, that class can only serialize one object -- being the list -- and if I try to append multiple ones it obviously just creates invalid JSON like {...}{...} which won't work.
Is there any way to do this? I'm insanely new to C# and ASP.NET MVC so forgive me if this is a dumb question :)
Edit: here's my code as of right now.
string chatLogPath = "path_to_a_text_file.txt";
IEnumerable<ChatMessage> q = ...
...
JavaScriptSerializer json = new JavaScriptSerializer();
return json.Serialize(q) + json.Serialize(chatLogPath);
Which will output the array like this in JSON { ... } followed by the chatLogPath { ... }. In other words, it can't work since that's invalid JSON.
The easiest way to get a single JSON object with the array and path together is to create a class or dynamic object with each as a property/field of it.
Class example:
public class ChatInformation {
public IEnumerable<ChatMessage> messages;
public string chatLogPath;
}
...
var output = new ChatInformation {
messages = ...,
chatLogPath = "path_to_a_text_file.txt"
};
return json.Serialize(output);
Dynamic example (requires .NET 4+):
dynamic output = new ExpandoObject {
messages = ...,
chatLogPath = "path_to_a_text_file.txt"
};
return json.Serialize(output);
Anonymous Type example (if you don't care to have another class, nor are you on .NET 4):
var output = new {
messages = ...,
chatLogPath = "path_to_a_text_file.txt"
};
return json.Serialize(output);

Categories