I would like to deserialize a JSON object like this:
[{"Response":"OK","UUID":"89172"},{"Response":"OK","UUID":"10304"}]
into a custom class where it has variables storing Response and UUID. However I would want to deserialize multiple data response such as above example. It will be great if I can use the method ForEach such that I can pop the data out accordingly. Can anyone advise? Many Thanks!
write this class
public class MyClass
{
public string Response { get; set; }
public string UUID { get; set; }
}
then you can deserialize it using the library newtonsoft.json
string jsonString = "[{"Response":"OK","UUID":"89172"},{"Response":"OK","UUID":"10304"}]";
...
...
var myListOfItems= JsonConvert.DeserializeObject<List<MyClass>>(jsonString);
foreach(var item in myListOfItems)
{
....
}
FULL CODE IN CONSOLE APPLICATION
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string jsonString = "[{'Response':'OK','UUID':'89172'},{'Response':'OK','UUID':'10304'}]";
var items= JsonConvert.DeserializeObject<List<MyClass>>(jsonString);
foreach (var item in items)
{
Console.WriteLine("UUUID: "+item.UUID);
Console.WriteLine("Response: " + item.Response);
Console.WriteLine();
}
Console.ReadKey();
}
}
public class MyClass
{
public string Response { get; set; }
public string UUID { get; set; }
}
}
I would use Json.Net for that.
Have a look at Json.Net help in the "Serializing and Deserializing JSON" section.
There they show you how to deserialize the json-string into an object.
You will need Newtonsoft.Json library for this to work:
public class A
{
public string Response { get; set; }
public string UUID { get; set; }
}
static void Main(string[] args)
{
var json = "[{\"Response\":\"OK\",\"UUID\":\"89172\"}, \"Response\":\"OK\",\"UUID\":\"10304\"}]";
var result = JsonConvert.DeserializeObject<IEnumerable<A>>(json);
foreach (var a in result)
Console.WriteLine("Response: {0} UUID: {1}", a.Response, a.UUID);
Console.ReadKey();
}
I've finally resolved this problem thanks with the help of #Newton Sheikh. Thank you first of all.
First I created a class (Student)
public class Student
{
public string Response { get; set; }
public string UUID { get; set; }
}
Then I imported the JSON.NET and created a function:
public List<Student> ReturnAllStudentsList()
{
string jsonString = "[{'Response':'OK','UUID':'89172'},{'Response':'OK','UUID':'10304'}]";
List<Student> Students = new List<Student>(); //Creates a list of custom Type: Student
var result = JsonConvert.DeserializeObject<List<Student>>(jsonString);
foreach (var student in result)
{
Students.Add(student);
}
return Students;
}
From this point, I have a list of Students. Then in my main program, I call this function:
private void button1_Click(object sender, EventArgs e)
{
List<Student> Students = ReturnAllStudentsList(); // Gets the list from JSON.
foreach(Student student in Students)
{
// Here I can access to each student for every loop cycle.
MessageBox.Show(student.Response);
}
}
Thank you #Newton Sheikh and others help! I hope this example code can help others too! Cheers.
Related
I am passing an object to a C# winform application via socketIO i manage to get the data, but having trouble getting the key value from the object, so far below is my code to capture the data from the socket server.
socket.On("traverseLeft", (data) =>
{
Invoke(new Action(() =>
{
MessageBox.Show(data.ToString());
}));
});
So my output is below, what I need to get is the interactive_link's value which is "sub", how can I achieve this on C#?
{
"msg":{
"interactive_link":"sub"
}
}
First, download the Newtonsoft NuGet package: Newtonsoft.Json from NuGet.
Then create the following classes:
public class RootObject
{
[JsonProperty("msg")]
public Message Message { get; set; }
}
public class Message
{
[JsonProperty("interactive_link")]
public string InteractiveLink { get; set; }
}
And finally do this:
var inputObj = JsonConvert.DeserializeObject<RootObject>(data);
var message = inputObj.Message.InteractiveLink;
MessageBox.Show(message);
Hope this helps.
You can also use JObject to read the properties
JObject obj = JObject.Parse(json);
Console.WriteLine(obj["msg"]["interactive_link"]);
You can create the model class as per your JSON response. You can create it online using http://json2csharp.com/
public class Msg
{
public string interactive_link { get; set; }
}
public class MyJson
{
public Msg msg { get; set; }
}
And then deserialize your json to this class using Newtonsoft.Json(nuget).
var myJson = JsonConvert.DeserializeObject<MyJson>(json);
And then access your data
var interactiveLink = myJson.msg.interactive_link;
If your data has a defined structure, you can use a Strongly-Typed manner. So you should define your classes first:
public class Msg
{
public string interactive_link { get; set; }
}
public class DataObject
{
public Msg msg { get; set; }
}
And the parse your JSON result to the defined object:
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<DataObject>(data);
I have a json file which has random names in roots but same structure in child elements. I would like to get all the child elements in an array or a list.
Sample json file :
{
"-LeHl495vL6vh-8CaLbD":{
"apiKey":"sr-tr-137-beea04e44cb452ba0da0ca090b7e61b4ec6ffc69"
},
"-LeHl6jrhUEMb7slZcpB":{
"apiKey":"sr-tr-137-aef7a23095c0c7baef1ef681bdd8bf9756ac2a17"
}
}
I have tried these classes but could not do it.
public class RequestedReport
{
public Dictionary<string, List<ReportData>> ReportDatas { get; set; }
}
public class ReportData
{
public string apiKey { get; set; }
}
So my expected output from deserialization is like List which contains all the apiKeys in json file.
Thanks in advance.
It looks to me like your JSON represents a Dictionary<string, ReportData> directly. There's no wrapper object, and no lists involved. If you deserialize your JSON to that type, it should be fine. Here's a complete example:
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
class Program
{
static void Main()
{
var json = File.ReadAllText("test.json");
var reports = JsonConvert.DeserializeObject<Dictionary<string, ReportData>>(json);
foreach (var pair in reports)
{
Console.WriteLine($"{pair.Key}: {pair.Value.ApiKey}");
}
}
}
public class ReportData
{
[JsonProperty("apiKey")]
public string ApiKey { get; set; }
}
If you just want the list of API keys, and you don't care about the field names associated with them, you can use:
var apiKeys = reports.Values.Select(x => x.ApiKey).ToList();
I am calling an external web service and this is what I get in response after posting to their server:
{
"status":200,
"data":{
"h21":{
"total_price":{
"acacia":{
"available":0,
"price":null,
"availability":false
},
"maple":{
"available":7,
"price":2399.0,
"availability":true
}
}
},
"h17":{
"total_price":{
"mahogany":{
"available":1,
"price":1899.0,
"availability":true
},
"oak":{
"available":0,
"price":null,
"availability":false
},
"maple":{
"available":6,
"price":1649.0,
"availability":true
}
}
}
}
}
I want this response to be converted into a list. I used jsontocsharp online converter to generate class and use code below:
var Jsonresult = JsonConvert.DeserializeObject<Sstageback.Models.Sstage.treeboRoomTypes.RootObject>(JsonReplace);
But the thing is mine is a dynamic JSON response which can change over course of time.
Note: The response which I get from the server is hotel and its room availability so while generating classes I can't generate with a single class file since the hotel id's may change also the room types and its availability also changes.
Example: h21 is one hotel id and total_price has its room type details similarly h17 is the next hotel and total_price has its room type details.
Basically, TotalPrice should be a Dictionary<string, Availability> or similar. It's not clear what list you'd have, but that's naturally a dictionary. That's then nested within a dictionary at the top level.
Sample code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
public class Response
{
public int Status { get; set; }
public Dictionary<string, Hotel> Data { get; set; }
}
public class Hotel
{
[JsonProperty("total_price")]
public Dictionary<string, Room> TotalPrice { get; set; }
}
public class Room
{
public int Available { get; set; }
public decimal? Price { get; set; }
public bool Availability { get; set; }
}
class Test
{
static void Main(string[] args)
{
var text = File.ReadAllText("test.json");
var response = JsonConvert.DeserializeObject<Response>(text);
foreach (var pair in response.Data)
{
Console.WriteLine($"Key: {pair.Key}");
foreach (var nestedPair in pair.Value.TotalPrice)
{
var room = nestedPair.Value;
Console.WriteLine($" {nestedPair.Key}: {room.Available}/{room.Price}/{room.Availability}");
}
}
}
}
Output:
Key: h21
acacia: 0//False
maple: 7/2399.0/True
Key: h17
mahogany: 1/1899.0/True
oak: 0//False
maple: 6/1649.0/True
You'll need to make a DTO model that corresponds with the response. The value of a attribute can change, that's no problem, as long as the type stays the same ( an int stays an int and a string stays a string).
Your Object could look like this:
public class Room{
public int Available { get; set;}
public int Price { get; set; }
public bool availability { get; set; }
}
public class Hotel{
public string Name { get; set; }
public List<Room> Rooms { get; set; }
}
You should convert Serialize and Deserialize this. This is only an example, you want your model to be 100% the same as your JSON.
For an easy conversion between Models and DTO, you could use AutoMapper: http://automapper.org/
I have a dictionary of strings and object that i obtained deserializing this json answer:
{"labels":[{"id":"1","descrizione":"Etichetta interna","tipo":"0","template_file":"et_int.txt"},{"id":"2","descrizione":"Etichetta esterna","tipo":"1","template_file":"et_ext.txt"}],"0":200,"error":false,"status":200}
using the code:
var labels = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
Now i want to loop only trought the objects inside the "labels" key.
I tried
foreach (var outer in labels["labels"]){/* code */}
but i got error:
CS1579: foreach statement cannot operate on variables of type 'object' because 'object' does not contain a public definition for 'GetEnumerator'.
Solved replacing the dictionary with a class, thank you
Create a class to deserialize your json:
To create classes, you can copy the json in clipboard and use the
Edit / Paste special / Paste JSON as class
in visual studio (I use vs2013).
[TestMethod]
public void test()
{
string json = "{\"labels\" : [{\"id\" : \"1\",\"descrizione\" : \"Etichetta interna\",\"tipo\" : \"0\",\"template_file\" : \"et_int.txt\"}, {\"id\" : \"2\",\"descrizione\" : \"Etichetta esterna\",\"tipo\" : \"1\",\"template_file\" : \"et_ext.txt\"}],\"0\" : 200,\"error\" : false,\"status\" : 200}";
var root = JsonConvert.DeserializeObject<Rootobject>(json);
foreach (var label in root.Labels)
{
//Use label.Id, label.Descrizione, label.Tipo, label.TemplateFile
}
}
public class Rootobject
{
public Label[] Labels { get; set; }
public int _0 { get; set; }
public bool Error { get; set; }
public int Status { get; set; }
}
public class Label
{
public string Id { get; set; }
public string Descrizione { get; set; }
public string Tipo { get; set; }
public string TemplateFile { get; set; }
}
You need to loop through your dictionary.
foreach(KeyValuePair<string, Object> entry in labels)
{
// do something with entry.Value or entry.Key
}
Once you start looping through it you will get access to key and value. Since you are interested to look at entry.value you can do operation on that easily. Currently your dictionary value is type of object which does not have an enumerator
Your problem is that you've defined the Type of Value for each dictionary entry as object. C# can't know how to loop over on object. So you need to work out what type is actually inside the object once the JavaScriptSerializer have parsed the JSON. One way is
var t = typeof(labels["labels"]);
Once you know what type the serializer is creating, all you need to do is cast the object back to that type. For example, assuming it's a list of objects
var labels = (List<object>)labels["labels"];
foreach (var label in labels)
{
}
Alternatively, if each object in the JSON is the same, you could try create the dictionary as the type you need. So you serializing becomes
var labels = new JavaScriptSerializer()
.Deserialize<Dictionary<string, List<object>>>(json);
A possible solution:
static void Main(string[] args) {
string json = #"{'labels':[{'id':'1','descrizione':'Etichetta interna','tipo':'0','template_file':'et_int.txt'},{'id':'2','descrizione':'Etichetta esterna','tipo':'1','template_file':'et_ext.txt'}],'0':200,'error':false,'status':200}";
var labels = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
IEnumerable inner_labels = labels["labels"] as IEnumerable;
if (inner_labels != null) {
foreach (var outer in inner_labels) {
Console.WriteLine(outer);
}
}
}
Otherwise, you can create a class with deserialization information and instruct the deserializer to deserialize your json string to that type:
using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Xml.Serialization;
[Serializable]
public class JsonData {
[XmlElement("labels")]
public List<JsonLabel> labels { get; set; }
[XmlElement("0")]
public int zero { get; set; }
[XmlElement("error")]
public bool error { get; set; }
[XmlElement("status")]
public int status { get; set; }
}
[Serializable]
public class JsonLabel {
[XmlElement("id")]
public int id { get; set; }
[XmlElement("descrizione")]
public string descrizione { get; set; }
[XmlElement("tipo")]
public int tipo { get; set; }
[XmlElement("template_file")]
public string template_file { get; set; }
}
class Program {
static void Main(string[] args) {
string json = #"your json string here...";
var jsonData = new JavaScriptSerializer().Deserialize<JsonData>(json);
foreach (var label in jsonData.labels) {
Console.WriteLine(label.id);
}
}
}
Could you please try below snippet?
It might be help you.
foreach (var item in labels["labels"] as ArrayList)
{
Console.Write(item);
}
Sorry, new to Json. Have read up but can't get this working. I have this json formatted string being returned on a .aspx page where I am using C#.
{"ContactsListResult":[{"Contact":"Fred Smith","ContactID":25},{"Contact":"Bill Wilson","ContactID":45}]}
I have a Contact object.
public class Contact
{
public string Contact { get; set; }
public int ContactID { get; set; }
}
I need to get each Contact into a Contact object and into a List of Contacts - just using whatever is built into Framework 4.0. I am not interested in the 'ContactsListResult' bit of the Json - I am just interested in the list of contacts within the square brackets.
using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
namespace ConsoleApplication1 {
class Program {
[Serializable]
public class ContactsListResult {
public string Contact { get; set; }
public int ContactID { get; set; }
} //
[Serializable]
public class CList {
public List<ContactsListResult> ContactsListResult = new List<ContactsListResult>();
} //
static void Main(string[] args) {
string s = "{\"ContactsListResult\":[{\"Contact\":\"Fred Smith\",\"ContactID\":25},{\"Contact\":\"Bill Wilson\",\"ContactID\":45}]}";
JavaScriptSerializer lSerializer = new JavaScriptSerializer();
CList lItems = lSerializer.Deserialize<CList>(s);
foreach (ContactsListResult lItem in lItems.ContactsListResult) Console.WriteLine(lItem.Contact + " " + lItem.ContactID);
Console.ReadLine();
} //
} // class
} // namespace
Please follow the details on my blog:
http://csharphardcoreprogramming.wordpress.com/2014/01/23/json-part-1-basics-follow-up-to-xml/
Bastian M.K. Ohta
DataContractJsonSerializer is the class you need to use. See here for a demo:
http://msdn.microsoft.com/en-us/library/hh674188.aspx
Also, google it. This took me 2 minutes of research.
Here's another stack overflow Q regarding the same item. Someone else recommends JSon.NET
Read JSON using DataContractJsonSerializer
You can use this library where you not have to decorate your clases without any Data Annotation... http://james.newtonking.com/json