Deserialize JSON using C# - c#

I am trying to deserialize this JSON string to different objects in C# using Newtonsoft.Json
{"apple":{"title":"apple","color":"red"},"banana":{"title":"banana","color":"yellow"}}
Note "apple" and "banana" in this example are dynamic values, so it's very well possible that suddenly it's called something others, e.g. ananas.
Now what I'm trying to do is deserialize this JSON string in a way that I can do a foreach loop through all the objects (Apple, Banana, ...) to read the value of the color field.
But apparently I'm doing something wrong, this is my code.
dynamic d = JObject.Parse(jsonString);
foreach (dynamic e in d)
{
Console.WriteLine(e.title);
}
Does anyone know why this does not work like this?

You want to do e.Value.title instead of just e.title.
DotNetFiddle example here.

e is a KeyValuePair<String,JToken> so we need to access e.Value to get the title.
var d = JObject.Parse(#"{""apple"":{""title"":""apple"",""color"":""red""},""banana"":{""title"":""banana"",""color"":""yellow""}}");
foreach (dynamic e in d)
{
Console.WriteLine(e.Value.title);
}

Try using System.Web.Script.Serialization then doing the following:
var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<Dictionary<string, dynamic>>(YOURJSON);
To use this do:
string item = dict["name"];
string itema = dict["item"]["thing"];
Hope this helps.

Related

Json newtonsoft : Deserialize string array from an Object

My JSON is a very long one and i am fetching only one section "parent_crumbs" from the long JSON
...................,
"parent_crumbs":["Platforms","New platform"],
"promise_by":"2016-08-01",
....
The code I used to fetch value of "parent_crumbs" is
JObject lp_p = JObject.Parse(response_json);
string val= lp_p["parent_crumbs"].ToString();
This returns the following value
"[\r\n \"Platforms\",\"New platform\"\r\n]"
Now I have to do a comparison with the first value from the array as the string is available in a Dictionary as key value and if available return ID
Packages = new Dictionary<string, int>();
Packages.Add("Platforms", 10212);
Packages.Add("New platform", 10202);
Packages.Add("Unknown platform", 10203);
int category=
if(Packages.ContainsKey(val))
{
Packages.TryGetValue(val, out category);
}
So with current code I can't do the comparison straight away due to presence of [\r\n etc.
How to get the value as a string Array without special chars like [\r\n .
Making Model Classes for the JSON for deserialization is not preferred way for me. Since creating class is a big job for me as lot of properties are there in JSON and is dynamic of nature
We can use the below code
var input = "[\r\n \"Platforms\",\"New platform\"\r\n]";
var array =(JArray) JsonConvert.DeserializeObject(input);
bool isEqual = array[0].Value<string>() == "Platforms";
you could also convert it to array with Linq
using System.Linq;
var tmp = lp_p["parent_crumbs"].Select(x => x.ToString());
foreach (var x in tmp)
{
Console.WriteLine(x.ToString());
}
By using Select, it will help you convert it to array rather than to string
You can use DeserializeAnonymousType method for that:
var myType = new
{
parent_crumbs = new []{ "" },
promise_by = default(DateTime)
};
var result = JsonConvert.DeserializeAnonymousType(json, myType);
int category = 0;
string key = result.parent_crumbs[0];
if(Packages.ContainsKey(key))
{
Packages.TryGetValue(key, out category);
}
References: DotNetFiddle Example, DeserializeAnonymousType

Deserialising a list of lists where outer list has no identifier without hard coding [duplicate]

I'm quite new to JSON, and am currently learning about (de)serialization.
I'm retrieving a JSON string from a webpage and trying to deserialize it into an object. Problem is, the root json key is static, but the underlying keys are dynamic and I cannot anticipate them to deserialize. Here is a mini example of the string :
{
"daily": {
"1337990400000": 443447,
"1338076800000": 444693,
"1338163200000": 452282,
"1338249600000": 462189,
"1338336000000": 466626
}
}
For another JSON string in my application, I was using a JavascriptSerializer and anticipating the keys using class structure. What's the best way to go about deserializing this string into an object?
Seriously, no need to go down the dynamic route; use
var deser = new JavaScriptSerializer()
.Deserialize<Dictionary<string, Dictionary<string, int>>>(val);
var justDaily = deser["daily"];
to get a dictionary, and then you can e.g.
foreach (string key in justDaily.Keys)
Console.WriteLine(key + ": " + justDaily[key]);
to get the keys present and the corresponding values.
You can use dynamic in .NET 4 or later. For example with JSON.NET I can do:
dynamic obj = JsonConvert.Deserialize<dynamic>("{x: 'hello'}");
You can then do:
var str = obj.x;
However, unsure how it will handle numeric keys. You can of course just use JObject directly itself, for example:
var obj = JObject.Parse("{'123456': 'help'}");
var str = obj["123456"];
Whenever you have JSON with dynamic keys it can usually be deserialized into a Dictionary<string, SomeObject>. Since the inner JSON keys are dynamic (in this question) the JSON can be modelled as:
Dictionary<string, Dictionary<string, int>>
I would recommend using NewtonSoft.Json (JSON.Net) or System.Text.Json (if you're working in .NET-Core 3.0 and up).
Newtonsoft.Json
Use DeserializeObject<T> from JsonConvert:
var response = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, int>>>(json);
System.Text.Json
Use Deserialize<T> from JsonSerializer:
var response = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, int>>>(json);
This is not convenient to use, because in с# can not be defined a variable starts with a number. Add prefix to keys.
Or try this:
string json = "
{ daily:[
{ key: '1337990400000', val:443447 },
{ key: '1338076800000', val:444693 },
{ key: '1338163200000', val:452282 },
{ key: '1338249600000', val:462189 },
{ key: '1338336000000', val:466626 }]
}";
public class itemClass
{
public string key; // or int
public int val;
}
public class items
{
public itemClass[] daily;
}
items daily = (new JavascriptSerializer()).Deserialize<items>(json);
Then you can:
var itemValue = items.Where(x=>x.key=='1338163200000').Select(x=>x.val).FirstOrDefault();

How to get the deep level node value easily when we don't have the object class with fastjson

I need to parse lots of long json strings. Newtonsoft.Json is slow and I try to use fastjson.
I don't have the object class so I use the following code to get values when using Newtonsoft.Json:
JObject jo = (JObject)JsonConvert.DeserializeObject(addressBook);
string floor = jo["Street"]["building"]["floor"].ToString();
When I turn to use fastjson and use the JSON.Parse(string), I got an Dictionary<string, object>. And if I want to get the 'floor' value, I need to do the casting for each level like below:
var ob = (Dictionary<string, object>)JSON.Parse(addressBook);
var street = (Dictionary<string, object>)ob["Street"];
var building = (Dictionary<string, object>)street["building"];
var floor= (Dictionary<string, object>)building["floor"];
Does anyone know fastjson support it or not? And can it still be fast?

How to parse Json objects inside array?

[{"conversation":{"id":"04d27d987de7f897580096b099815691cd4a89_ecf47fb8-cd72-4e5d-925c-5a63aa2fb315","wid":"04d27d987de7f897580096b099815691cd4a89","nicknames":{"owner":"Wiz_boltebony","originator":"Username123"},"group_token":"5a4b2b9d-ed39-4029-a76e-347a8c99806b"}},{"conversation":{"id":"05043a6393ec32806194414f2239a8697fa788_ecf47fb8-cd72-4e5d-925c-5a63aa2fb315","wid":"05043a6393ec32806194414f2239a8697fa788","nicknames":{"owner":"Summer_Reflection","originator":"Wiz_boltebony"},"group_token":"0b77eb02-aa57-4811-91fd-5fa61997b6a0"}}]
I want to parse out all of the (group_token":"0b77eb02-aa)...etc values from this json "array".
Here is my code:
dynamic j = JsonConvert.DeserializeObject(contents);
foreach (var c in j[0]["conversation"])
{
Console.WriteLine(c["group_token"]);
}
Here is an image on how the JSON is laid out:
http://gyazo.com/5840a31b71d4cbea626899030debe5d8
My code doesn't work at all! How do I go about extracting these group_token values?
You need to change your code a little bit (iterate through objects, not properties);
dynamic j = JsonConvert.DeserializeObject(contents);
foreach (var c in j)
Console.WriteLine(c["conversation"]["group_token"]);
Your current code iterates through properties of first conversation object and tries to get group_token child of each property, which is wrong.
You can try below as well. Totally agreed with #Ulugbek Umirov
var _jArr = (JArray)JsonConvert.DeserializeObject(contents);
IEnumerable<string> _groupToken = _jArr.Select(conv => conv["conversation"]["group_token"].ToString());

Cast Object to Generic List

I have 3 generict type list.
List<Contact> = new List<Contact>();
List<Address> = new List<Address>();
List<Document> = new List<Document>();
And save it on a variable with type object. Now i nedd do Cast Back to List to perfom a foreach, some like this:
List<Contact> = (List<Contact>)obj;
But obj content change every time, and i have some like this:
List<???> = (List<???>)obj;
I have another variable holding current obj Type:
Type t = typeof(obj);
Can i do some thing like that??:
List<t> = (List<t>)obj;
Obs: I no the current type in the list but i need to cast , and i dont now another form instead:
List<Contact> = new List<Contact>();
Lots of trial and error gave me this on SL 5 but it should also work on a regular C#. You also need to add LINQ to your using list for the last half to work.
List<object> myAnythingList = (value as IEnumerable<object>).Cast<object>().ToList()
Enjoy!
What a sticky problem. Try this:
List<Contact> c = null;
List<Address> a = null;
List<Document> d = null;
object o = GetObject();
c = o as List<Contact>;
a = o as List<Address>;
d = o as List<Document>;
Between c, a, and d, there's 2 nulls and 1 non-null, or 3 nulls.
Take 2:
object o = GetObject();
IEnumerable e = o as IEnumerable;
IEnumerable<Contact> c = e.OfType<Contact>();
IEnumerable<Address> a = e.OfType<Address>();
IEnumerable<Document> d = e.OfType<Document>();
I had the same problem and solved it by looking at the purpose of the casted objects. Do you really need to cast it to the specific (closed) generic types? In my case the (open) generic type had an interface which I used to cast it to.
var list = obj as IUsefulInterface;
list.MethodThatIAmInterestedIn();
I had this problem when writing a Validation Attribute where I received an object from the ValidationContext and knew that it needed to be a list, but not what it was a list of. It threw an exception when I tried to cast it as IEnumerable<object> but it could be cast as IEnumerable which then allowed the .Cast<object>() via linq.
In the end what worked was:
var enumerable = listObject as IEnumerable;
var list = enumerable.Cast<object>().ToList();
A general solution like this (to instantiate a type with a generic parameter based on a System.Type object) is not possible. If you're really just dealing with these three types, though, then you're in luck because it's pretty easy:
Type t = typeof(obj);
if (t == typeof(List<Contact>)) {
var contactList = (List<Contact>)obj;
// do stuff with contactList
} else if (t == typeof(List<Address>)) {
var addressList = (List<Address>)obj;
// do stuff with addressList
} else if (t == typeof(List<Document>)) {
var documentList = (List<Document>)obj;
// do stuff with documentList
}
No, you can't cast without going around corners (this is: reflection), generic type parameters have to be known at compile time. You can of course do something like this:
content.Where(o => o is type).ToList().Foreach(stuff);
I ran into same problem - I have a collection which data type is only known at run time and I can't cast it to anything. None of the solutions above worked. Finally I solved it by serializing to JSON and de-serializing back. Of course it's not ideal, but may help someone.
string jsonString = JsonConvert.SerializeObject(myObject);
jsonString = "{ values:" + jsonString + "}";
JObject j = JObject.Parse(jsonString);
//now we can iterate over the list
foreach (var x in j["values"])
{
string name = x.ToString();
...
}
Employee employee=new Employee();
List<Employee> emplist=new();
emplist.Add(employee);
This is correct way
Thank you
You might need to do:
if(object is List)
{
list = (List)object
}

Categories

Resources