Getting nested data out of JSON in C# - c#

I have some JSON with Two objects and these each have 3 objects nested.
{
"FirstPerson": {
"number": "101",
"a10": "1001",
"a20": "1002"
},
"SecondPerson": {
"number": "102",
"a10": "2001",
"a20": "2001"
}
}
In c# asp.net mvc2 I've been able to get to "FirstPerson" or "SecondPerson" using a Hashtable but how do I get to "number" or "a10" when I know "FirstPerson"?
e.g. an objects inside an object.
Is a Hashtable the best use for this or should I be using something else?
Thanks in advance.

I found that solution for your problem may be give a clue to solve that
Want to convert a C# object into it's JSON equivalent? Here is a simple object from the System.Web.Script namespace that does exactly that:
System.Web.Script.Serialization.JavaScriptSerializer . It is stored in the System.Web.Extentions DLL (.Net Framework 3.5 only)
Using this object we serialize and deserialize objects in C#. Here is a quick sample:
A simple Employee object:
public class Employee
{
public string Name { get; set; }
public string Age { get; set; }
public string ID { get; set; }
}
Adding some instances of them to a List:
Employee oEmployee1 =
new Employee{Name="Pini",ID="111", Age="30"};
Employee oEmployee2 =
new Employee { Name = "Yaniv", ID = "Cohen", Age = "31" };
Employee oEmployee3 =
new Employee { Name = "Yoni", ID = "Biton", Age = "20" };
List oList = new List()
{ oEmployee1, oEmployee2, oEmployee3 };
Serializing then:
System.Web.Script.Serialization.JavaScriptSerializer oSerializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
string sJSON = oSerializer.Serialize(oList);
And here is the output:
[{"Name":"Pini","Age":"30","ID":"111"},
{"Name":"Yaniv","Age":"31","ID":"Cohen"},
{"Name":"Yoni","Age":"20","ID":"Biton"}]
For your consideration here is the link http://blogs.microsoft.co.il/blogs/pini_dayan/archive/2009/03/12/convert-objects-to-json-in-c-using-javascriptserializer.aspx

I have had good results using JsonConvert. It seems to do a good job of knowing what to do with collections. Just define the class you want to de-serialize to and have at it.
http://james.newtonking.com/projects/json-net.aspx
Example:
MyCollection col = JsonConvert.DeserializeObject<MyCollection>(this.HttpContext.Request.Params[0]);
Where MyCollection is a class which contains a collection of, in your case, people.

You could assign the JSON object to a dynamic variable and access the properties that way (only in C# 4.0 though)
dynamic jsonData = jsonObject;
int workflowNum = jsonData.SecondPerson[0].workflow;

Related

Nested list of constant strings in C#

Any way I can store this data in a clean way, and preferably use variable names instead of strings as keys to avoid typos? E.g. UNITED_STATES = "201" instead of "United States" = "201".
{
"countries": {
"id": "123",
"data" {
"United States": "201"
"Canada": "202",
}
},
"departments": { ... }
}
I started with KeyValuePairs like this, but nesting data in here seems like a bad idea.
private static readonly List<KeyValuePair<string, string>> CategoryIds = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Countries", "123"),
new KeyValuePair<string, string>("Departments", "124")
};
Two approaches to deserialize JSON here.
Strong typing approach (good approach):
public class A
{
public B Countries {get;set;}
public C Departments {get;set;}
}
public class B
{
public int Id {get;set;}
public D Data {get;set;}
}
...
var result = JsonConvert.DeserializeObject<A>(json);
You create DTO objects manually and just expect them to deserialize successfully.
Dynamic approach (bad but sometimes acceptable approach):
dynamic result = JsonConvert.DeserializeObject(json);
var data = result.countries.data;
You create some "bag of things" (dynamic is basically a bunch of hierarchical Dictionary wrapped into syntax sugar cane), don't really care about all of them, and just want some of its properties.
Maybe you could use json.net JObject?
It allows you to work with dynamic objects and convert them to and from json strings
Documentation for JObject
https://www.newtonsoft.com/json/help/html/QueryingLINQtoJSON.htm
Nuget:
https://www.nuget.org/packages/Newtonsoft.Json/
You can use a dictionary<k,v> for this purpose along with a enum like below probably
enum CountryVal
{
UnitesStates,
Canada
}
With a model structure like
public class Countries
{
public string id { get; set; }
public Dictionary<CountryVal, int> Data { get; set; }
}
public class Departments
{
public string id { get; set; }
}
public class RootObject
{
public Countries countries { get; set; }
public Departments departments { get; set; }
}
You can create a public class as below and you can then call country value like CountriesConstants.UNITED_STATES in your code and if you need to change the value just update it in CountriesConstants class
public class CountriesConstants
{
public const string UNITED_STATES = "201";
public const string Canada = "202";
//Add More
}
NJsonSchema is a library that will enable you to generate code in csharp as well as few other languages from a standard json schema. It is very powerful and configurable, and can pave most of the way on your behalf. But as i said it will expect an standard json schema as for the source of generation.
var schema = NJsonSchema.JsonSchema4.FromFileAsync(filename);
var generator = new CSharpGenerator(schema.Result);
var file = generator.GenerateFile();
Above is the minimum amount of code required to generate csharp classes from json schema. you can define settings and pass to the generator function to service your special needs of course.
github page for this library:
NJsonSchema github
Nuget page:
NJsonSchema Nuget

json to C# objects

I receive a JSON string from a external system and I want to turn in to C# objects. The problem is that the "CAR" objects are unique in the string and I do not know how many there is (0 to many).
Now, It doesn't make sense to hardcode classes for each "CAR" like class: CAR1, class: CAR2 and so on. I tried to create a general CAR class and was thinking I could loop throu the JSON and create CAR objects.
The problem is that I cant't identify and find each CAR dynamically.I find the attributes and values for "CAR1" by hardcode "CAR1".
I would like to find a solution like:
foreach(item.key where key starts with "CAR")
Tried the following:
var expConverter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(jsondata, expConverter);
dynamic json = Newtonsoft.Json.JsonConvert.DeserializeObject(jsondata);
foreach (var itm in obj)
{
string s = itm.Key;
if(s.StartsWith("CAR"))
{
CarObj = new Car();
CarObj.HP = json.CAR1[0].HORSEPOWER[0];
CarObj.COLOR = json.CAR1[0].COLOR[0];
// Would like to use something like
// CarObj.HP = json.**item.key**[0].HORSEPOWER[0];
}
}
{
"CAR1": [{
"HORSEPOWER": ["180", "int", "Hp"],
"COLOR": ["GREEN", "string", "COLOR"]
}],
"CAR2": [{
"HORSEPOWER": ["200", "int", "Hp"],
"COLOR": ["BlUE", "string", "COLOR"]
}]
}
You're not forced to use dynamic right away. First use the strongly-typed APIs to find the right portion of the JSON, then switch to dynamic:
var obj = JObject.Parse(json);
foreach (var element in obj)
{
if (element.Key.StartsWith("CAR"))
{
dynamic value = element.Value;
var carObj = new Car();
carObj.HP = value[0].HORSEPOWER[0];
}
}
You can deserialize as Dictionary<string,List<CarDetails>>
public class CarDetails
{
public List<string> HORSEPOWER { get; set; }
public List<string> COLOR { get; set; }
}
and then iterate the dictionary to get the results.

How to deserialize json and retrieve specific property values in c#

I'm quite new to JSON with C# (Using VS2017). Tried accessing each element of this object via code (e.g. Getting the strings "Obj1", "Obj2", "Obj3" and then the values of each of their members (Id and name).
I do not know in advance how many "ObjX" there will be or their names. I'm trying to load this list into some class and then convert it into a CSV (or SQL inserts).
Tried with JSON.net and JsonFx but I think my skills are just not strong enough to understand how to do this other than brute-force string manipulation functions. Can anyone help?
{
"OBJ1":{
"id":1,
"name":"Name1",
},
"OBJ2":{
"id":2,
"name":"Name2",
},
"OBJ3":{
"id":3,
"name":"Name3",
}
}
Create a class, MyClass with two properties, int Id and string Name.
public class MyClass
{
public int Id {get; set;}
public string Name {get;set;}
}
Then, depending on how you want to do it you can either deserilize it to a Dictionary or create a MyClassRoot object with three MyClass properties.
I recommend the Dictionary approach.
If you use the Dictionary approach your code will still work if more properties gets added to the JSON. If you use the MyClassRoot solution you will need to add the corresponding property to the MyClassRoot if the json updates.
Then with JSON.Net you can deserialize the object like this.
var result = JsonConvert.DeserializeObject<Dictionary<string, MyClass>>(json);
The "OBJ1", "OBJ2" and so on will then be keys in the dictionary and you can access the values like this:
var obj1 = result["OBJ1"];
var obj1Name = obj1.Name;
var obj1Id = obj1.Id;
To get all the MyClass objects to a list, simply do the following:
var list = result.ToList();
MyClassRoot approach(not recommended at all, just a POC):
public class MyClassRoot
{
public MyClass Obj1 {get;set;}
public MyClass Obj2{get;set;}
public MyClass Obj3{get;set;}
}
var result = JsonConvert.DeserializeObject<MyClassRoot>(json);
var obj1Name = result.Obj1.Name;
var obj1Id = result.Obj1.Id;

JSON Newtonsoft C# Good Practice for Serialize/ Deserialize Lists of Objects

I've readed others posts here about this question
Serializing a list of Object using Json.NET
Serializing a list to JSON
Merge two objects during serialization using json.net?
All very useful. Certain, I can serialize in one json two lists, but I cant deserialize it.
I´m working with Json Newtonsoft, C#, MVC5, framework 4.5. This is the scenario:
C# CODE
public class User
{
public int id { get; set; }
public string name { get; set; }
}
public class Request
{
public int id { get; set; }
public int idUSer{ get; set; }
}
List<User> UserList = new List<User>();
List<Request> RequestList = new List<Request>();
string json= JsonConvert.SerializeObject(new { UserList, RequestList });
JSON RESULT
{
"UserList":[
{
"id":1,
"name":"User 1"
},
{
"id":2,
"name":"User 2"
},
{
"id":3,
"name":"User 3"
}
],
"RequestList":[
{
"id":1,
"idUSer":1
},
{
"id":2,
"idUSer":1
},
{
"id":3,
"idUSer":1
},
{
"id":4,
"idUSer":2
}
]
}
C# DESERIALIZE
I dont Know how configure the settings of Json.Deserialize< ?, Settings>(json) for indicate what types of objects are being deserialized.
Change of approach
So that, change of approach, I've created a new class "Cover" in order to put the lists together and serialize one object
public class Cover
{
private List<User> user = new List<User>();
private List<Request> request = new List<Request>();
public List<User> User
{
get { return user;}
set { User = value;}
}
public List<Request> Request
{
get {return request;}
set {Request = value;}
}
}
SERIALIZE
string json = JsonConvert.SerializeObject(cover);
JSON The json result is the same.
DESERIALIZE
Cover result = JsonConvert.DeserializeObject<Cover>(json, new
JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
It's work fine. My situation is resolved but I have doubts about concepts, in my mind something is not clear:
MY QUESTIONS ARE:
For the first aproach:
Do you think that there is a way to deserialize a json with different lists of objects? Is not a good practice?
Second aproach: Why jsons are equals for first situation?
In JSON.NET you need to specify the type you're about to deserialize, by supplying its name as a type argument to DeserializeObject.
However, in this line:
string json= JsonConvert.SerializeObject(new { UserList, RequestList });
you create anonymous object and then serialize it - new { UserList, RequestList }. So there is the catch - you cannot use anonymous type as type arguments.
To handle such situations, JSON.NET provides DeserializeAnonymousType<>. It doesn't require you to supply the type argument; actually you can't as you going to deserialize anonymous type. Instead it is inferred from the type of the second argument, passed to the method. So you just create a dummy, anonymous object, without data and pass it to this method.
// jsonData contains previously serialized List<User> and List<Request>
void DeserializeUserAndRequest(string jsonData)
{
var deserializedLists = new {
UserList = new List<User>(),
RequestList = new List<Request>()
};
deserializedLists = JsonConvert.DeserializeAnonymousType(jsonData, deserializedLists);
// Do your stuff here by accessing
// deserializedLists.UserList and deserializedLists.RequestLists
}
Of course this all works fine, but this approach suggests that you already know the structure of the serialized data. If this structure doesn't match the structure of the initialized by you anonymous type you'll get nothing after the DeserializeAnonymousType method. And this is valid not just for the type of the properties of the anonymous type, but for their names too.
To your first question:
I would consider the option with the Cover class the 'best practice' as you are using the same model for serialization and deserialization and it's all up to Json.NET to figure out how to do the (de)serialization magic.
If for some reason you don't want to use this approach, there are two other options:
Anonymous types: http://www.newtonsoft.com/json/help/html/DeserializeAnonymousType.htm
Deserializing into a dictionary: http://www.newtonsoft.com/json/help/html/DeserializeDictionary.htm
To your second question - Are you sure the generated JSON is absolutely the same with both approaches? (You can use a tool like www.diffchecker .com to verify)
With your second approach the top-level names should be different - it should be 'Users' instead of 'UserList' and 'Requests' instead of 'RequestList'

Deserialize JSON Web Response in C#

I am working with a REST API and getting an HTTP response in JSON format. The JSON string contains an object as the first and only "top-level" or "root-level" key with an array of objects as its value.
Ultimately, I need to pass each of the objects in the array to a SQL query, which I intend to do by creating a List and iterating over the List with a foreach loop.
Here's a sample of the JSON response:
{
"blueplates": [
{
"Appetizer": 26,
"Salad": 21,
"Soup": "SheCrab",
"Entree": 6434,
"Side": 2303093,
"Desert": 0,
"Beverage": "Sweet Tea + SoCo"
},
{
"Appetizer": 27,
"Salad": 21,
"Soup": "Tomato Bisque",
"Entree": 6434,
"Side": 2303093,
"Desert": 0,
"Beverage": "Lemonade + Rum"
},
{
"Appetizer": 28,
"Salad": 21,
"Soup": "Peanut",
"Entree": 6434,
"Side": 2303093,
"Desert": 0,
"Beverage": "Ginger Ale + Whiskey"
}
]
}
The approach that I am taking is to create two classes (consistent with the result that I've gotten from http://json2csharp.com/) - a RootObject class and a Blueplate class.
The classes are structured like so:
public class Blueplate
{
public int Appetizer { get; set; }
public int Salad { get; set; }
public string Soup { get; set; }
public int Entree { get; set; }
public int Side { get; set; }
public int Desert { get; set; }
public string Beverage { get; set; }
}
public class RootObject
{
public List<Blueplate> blueplates { get; set; }
}
I am using the JavaScriptSerializer class from the System.Web namespace. I've tried to manually re-format the JSON in order to validate my basic usage of JavaScriptSerializer, so the following code compiles and writes the value of the "Appetizer" key to the console, awaiting keyboard input after each value is displayed:
var response = "[{\"Appetizer\":26,\"Salad\":21,\"Soup\":\"SheCrab\",\"Entree\":6434,\"Side\":2303093,\"Desert\":0,\"Beverage\":\"Sweet Tea + SoCO\"}, {\"Appetizer\":27,\"Salad\":21,\"Soup\":\"Tomato Bisque\",\"Entree\":6434,\"Side\":2303093,\"Desert\":0,\"Beverage\":\"Lemonade + Rum\"}, {\"Appetizer\":28,\"Salad\":21,\"Soup\":\"Peanut\",\"Entree\":6434,\"Side\":2303093,\"Desert\":0,\"Beverage\":\"Ginger Ale + Whiskey\"}]";
JavaScriptSerializer deSerializedResponse = new JavaScriptSerializer();
List<Blueplate> blueplates = (List<Blueplate>)deSerializedResponse.Deserialize(response, typeof(List<Blueplate>));
for (int i = 0; i < blueplates.Count; i++)
{
Console.WriteLine(blueplates[i].Appetizer);
Console.ReadLine();
}
The problem that I am having is dealing with the root tag and making use of the RootObject class.
I've tried using variations of statements like the following, along with variations of for and foreach loops:
RootObject rootObject = (RootObject) deSerializedResponse.Deserialize(response, typeof(RootObject));
Apparently, I am confused on several points:
Mapping the root JSON object to the C# RootObject class
Mapping the objects in the root JSON object's array value to the C# Blueplate class, OR
Mapping the objects in the root JSON object's array value to the blueplates property of the RootObject class
Enumerating and looping over the blueplates property of the RootObject class
Casting or converting the object type returned by the Deserialize method as a List of Blueplate objects
Finally, please note that I wish to use native Microsoft assemblies, rather than third-party packages like JSON.NET. I understand that JSON.NET may perform better, and I've read a number of posts that emphasize JSON.NET's ease of use. If you would insist on JSON.NET, please enlighten on me how JSON.NET is handling the root object.
Still, the accepted answer will address a native solution. The question is:
how can I use the native Microsoft class JavaScriptSerializer to deserialize a JSON response with a root object that has an array of objects as its value, where the target values are the objects in the array, to pass a List to a SQL query?
The first Json does work with my test:
Edit: changed to foreach.
var response = "{blueplates :[{\"Appetizer\":26,\"Salad\":21,\"Soup\":\"SheCrab\",\"Entree\":6434,\"Side\":2303093,\"Desert\":0,\"Beverage\":\"Sweet Tea + SoCO\"}, {\"Appetizer\":27,\"Salad\":21,\"Soup\":\"Tomato Bisque\",\"Entree\":6434,\"Side\":2303093,\"Desert\":0,\"Beverage\":\"Lemonade + Rum\"}, {\"Appetizer\":28,\"Salad\":21,\"Soup\":\"Peanut\",\"Entree\":6434,\"Side\":2303093,\"Desert\":0,\"Beverage\":\"Ginger Ale + Whiskey\"}]}";
JavaScriptSerializer deSerializedResponse = new JavaScriptSerializer();
RootObject root = (RootObject)deSerializedResponse.Deserialize(response, typeof(RootObject));
foreach (Blueplate plate in root.blueplates)
{
Console.WriteLine(plate.Appetizer);
Console.ReadLine();
}
RootObject objRootObject = new RootObject();
HttpResponseMessage apioresponse = { "blueplates": [ Your response] } ;
string responseString = await apioresponse.Content.ReadAsStringAsync();
objRootObject = JsonConvert.DeserializeObject<RootObject>(responseString);

Categories