Deserialize a complex dynamic JSON string - c#

What if the object to deserialize looked like this (where the keys Ioc, Name, id and timestamp are static, and the fields key is dynamic - meaning that it may contain a variable amount of items)???
{
"moduleinstances": [
{
"Ioc": "ioc1",
"Name": "name1",
"fields": {
"PV_PREFIX": "PIPE",
"TIMEOUT": "1"
},
"id": 25,
"timestamp": "/Date(1393518678000)/"
}
]
}
How to deserialize this kind of strings?

The secret is to keep your deserialized JSON in the most general form possible:
Dictionary<string, object> theData= new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(jsonString);
Dictionary<string, object> fieldsNode = (Dictionary<string, object>)theData["fields"];
string pv_prefix = (string)fieldsNode["PV_PREFIX"];
string timeout = (string)fieldsNode["TIMEOUT"];
The call to Deserialize() creates a tree of Dictionary<string, object> that you can traverse at will.

Related

Json Object deserialize to a List<class>

I have a Json string containing arrays and a single key with a value as you can see below.
{
"MSG": "Hallo Stackoverflow!",
"0": {
"ID": "2",
"Subject": "Danish",
"Message": "Message",
"DateEnd": "2016-02-28 00:00:00"
},
"1": {
"ID": "2",
"Subject": "Math",
"Message": "Message",
"DateEnd": "2016-02-29 00:00:00"
}}
I pass this to a JObject to get the MSG value, then remove it from the json. However, when key is gone, the numbers of the array gets deleted and I cannot pass it through my code:
JObject data = JObject.Parse(json);
string MSG = data["MSG"].ToString();
data.Remove("MSG");
List<HomeWork> homework = JsonConvert.DeserializeObject<List<HomeWork>>(json);
I get an error:
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Memento.HomeWork]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
If I generate it as an array without the key, it works fine.
You are actually trying to deserialize a JSON object rather than a JSON array.
Note that the following would be a JSON array (and you would be able to deserialize it into a List<Homework>):
[{
"ID": "2",
"Subject": "Danish",
"Message": "Message",
"DateEnd": "2016-02-28 00:00:00"
},
{
"ID": "2",
"Subject": "Math",
"Message": "Message",
"DateEnd": "2016-02-29 00:00:00"
}]
In order to deserialize this JSON object, you must use a Dictionary<TKey, TValue> (because you don't know the object's keys beforehand), which in your case is Dictionary<int, Homework>:
Dictionary<int, Homework> homeworks = JsonConvert.DeserializeObject<Dictionary<int, Homework>>(json);
Homework hw = homeworks[0]; //This will be your first homework, the one with ID = 2

serialize dictionary with Json.net and select query on entity

I have code that looks like this...
var records = from part in this.DataWorkspace.AUTOData.TestParameterViews
select new
{Name = part.ParamName, Val = part.CurrentValue}
File.WriteAllText(#"c:\params.json", JsonConvert.SerializeObject(new{parameters = records }, Formatting.Indented));
The generated json file looks like this.....
{
"parameters": [
{
"Name": "Var1",
"Val": 6666.0
},
{
"Name": "Var2",
"Val": 1.0
},
{
"Name": "Var3",
"Val": 5500.0
},
And so on...listing all the members within the entity.
PROBLEM: I would like the json output to be in a dictionary format (shown below), but still query the entity.
"parameters": {
"Var1": 6666.0,
"Var2": 1.0,
"Var3": 5500.0,
I have tried the following code but am hung up on syntax. Specifically Intellisense is indicating an error on the select saying "Cannot implicitly convert type....An explicit conversion exists(are you missing a cast?)
Dictionary<string, float> records = from part in this.DataWorkspace.AUTOData.TestParameterViews
select new Dictionary<string, float>
{Name = part.ParamName, Val = part.CurrentValue}
File.WriteAllText(#"c:\params.json", JsonConvert.SerializeObject(new{parameters = records }, Formatting.Indented));
Thanks for your help!
Create the dictionary. Then loop thru TestParameterViews adding to the dictionary. Then serialize.
Dictionary<string, float> records = new Dictionary<string, float>();
this.DataWorkspace.AUTOData.TestParameterViews.ForEach(part => part.ParamName, part.CurrentValue);
File.WriteAllText(#"c:\params.json", JsonConvert.SerializeObject(new { parameters = records }, Formatting.Indented));

Json children properties to dictionary

I'm trying to extract a list of dates for a property of all children nodes on a JToken but cannot get the syntax correct.
I want to get a list of dates in property "timeStamp": "2013-09-11T00:30:00Z" so I can determine the min/max dates for all child nodes.
I've tried the following which returns an anonymous type and makes it difficult to use the returned object.
var timeStamps = Jarr.Select(x => new
{
timeStamp = (DateTime)x.SelectToken("timeStamp")
});
How can I get say a List<string> or List<DateTime> only of all child timestamps?
Is it possible to get a Dictionary<string, DateTime> of id, timestamp?
The Json looks like this, so essentially from LEVEL1 I want to check all children, children of children for the same property.
{
"children": [
{
"type": "LEVEL2",
"name": "Item1",
"id": "1.7193",
"timeStamp": "2013-09-11T00:30:00Z",
},
{
"type": "LEVEL2",
"name": "Item2",
"id": "1.7194",
"timeStamp": "2013-09-11T00:30:00Z",
},
{
"type": "LEVEL2",
"name": "Item3",
"id": "1.7191",
"timeStamp": "2013-09-11T00:30:00Z",
}
],
"type": "LEVEL1",
"name": "Stock-FRT54443",
"id": "1000145",
"countryCode": "en"
}
and method
void AddNodes(TreeView treeView, JObject jObj, TreeNodeCollection parent)
{
JToken Jarr = null;
Dictionary<string, string> marketProperties = new Dictionary<string, string>();
foreach (var property in jObj.Properties())
{
if (property.Name == "children")
{
Jarr = property.Value;
}
else
{
string key = property.Name;
string prop = property.Value.ToString();
marketProperties.Add(key, prop);
}
}
if (marketProperties["type"] == "LEVEL1")
{
//Not working!
var timeStamps = Jarr["timeStamp"].Values<string>();
}
}
When you use the 'new' keyword it's going to create an anonymous type. You're creating a list of objects with a timestamp property rather than a list of DateTimes. All you need to do to get your date list is to change it to:
DateTime timeStamps = Jarr.Select(x => (DateTime)x.SelectToken("timeStamp")).ToList();
It's also possible to get a dictionary:
Dict<string,DateTime> dictionary = Jarr["children"].ToDictionary(x=>x["Id"].ToString(),x=>(DateTime)(x["timeStamp"]));
The second is untested but should give you the general idea.

how to add an object to a dictionary in c#?

I need to create a JSON structure in the following format:
{
"test": [
{
"mode": "2",
"test": "test3"
},
{
"mode": "1",
"test": "test3"
}
]
}
So whenever a JSON structure is created, it should be appended to the test element.
So initially I will have only the value:
string json=#"{""testfun"": [ {""mode"": ""2"", ""test"": ""test3"" } ]}";
Dictionary<string, object> objtestnew2 = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
So how can I append when I get the next JSON structure to the existing dictionary element?
Split your creation of the dictionary, and the deserialization into two different steps.
The first time the method is called it should see if the dictionary exists, and if it doesn't create one. If it does exist, then you can append the deserialized data to that dictionary.
You can deserialize the second dictionary then just merge it into the first one. The simplest way to do it is a simple loop:
string json=#"{""testfun"": [ {""mode"": ""2"", ""test"": ""test3"" } ]}";
Dictionary<string, object> dict = (new JavaScriptSerializer()).Deserialize<Dictionary<string, object>>(json);
string json2=#"{""testfun"": [ {""mode"": ""1"", ""test"": ""test3"" } ]}";
Dictionary<string, object> dict2 = (new JavaScriptSerializer()).Deserialize<Dictionary<string, object>>(json2);
// loop through and update/add the items to the first dictionary
foreach(var item in dict2)
dict1[item.Key] = item.Value;

Parse Json without any property in c#

In my desktop application i want to parse a json file to Key,Value pair List .
Where Key is unique one and Value contains another list of Key,Value Pair . The striuctre of json string is
{
"mainkey1": {
"subkey10": [
value1
],
" subkey11":[
value2
]
},
"mainkey2": {
"subkey20": [
value0
],
"subkey21": [
value1
]
},
"mainkey3": {
"subkey30": [
value0
],
"subkey31": [
value1
]
}
.
.
.
.
.
}
How can i convert this kind of json string to some .Net object of key,value strings
key=string type value List
Any idea ?
Try deserializing to:
Dictionary<string, Dictionary<string,List<object>>>
...or use something like Newtonsoft's JSON library which has a JObject class representing any sort of JSON object .
Update:
To use the much-easier JavaScriptSerializer, just do this:
var serializer = new JavaScriptSerializer();
var obj = serializer.Deserialize<Dictionary<string, Dictionary<string, List<object>>>>(json);

Categories