Loop through JSON object and values to List in C# - c#

I am trying to get values from a JSON object and save them into 2 lists. I am struggling with understanding how to loop through the JSON object to get the JSON array values.
I believe I am Deserializing correctly, but I am stuck going forward. Here is what I currently have
JObject jsonResult = {"foodtype": ["Pizza", "Pasta", "Bread"],
"drinks": ["Coke", "Root Beer"]}
public class Rootobject
{
public string[] foodType { get; set; }
public string[] drinks { get; set; }
}
var allObject = JsonConvert.DeserializeObject<Rootobject>(jsonResult.ToString());
What I am wanting is for 2 lists to be generated from the JSON result like so:
List<string> food = new List<string> {Pizza, Pasta, Bread}
List<string> drink = new List<string> {Coke, Root Beer}

Your code is invalid, the snippet below is incorrect:
JObject jsonResult = {"foodtype": ["Pizza", "Pasta", "Bread"],
"drinks": ["Coke", "Root Beer"]}
You need to have a string which can be deserialized.
The code below should help you:
static void Main(string[] args)
{
var objectToSerialize = new Rootobject()
{
Drinks = new [] {"Coke", "Root Beer" },
FoodType = new[] { "Pizza", "Pasta", "Bread" }
};
var serializedByTheLib = JsonConvert.SerializeObject(objectToSerialize);
string jsonResult =
"{ \"foodtype\": [\"Pizza\", \"Pasta\", \"Bread\"], \"drinks\": [\"Coke\", \"Root Beer\"] }";
var deserializedObject = JsonConvert.DeserializeObject<Rootobject>(jsonResult);
}
public class Rootobject
{
[JsonProperty("foodType")]
public string[] FoodType { get; set; }
[JsonProperty("drinks")]
public string[] Drinks { get; set; }
}
Key concepts:
An object can be serialized to JSON
A JSON string can be deserialized to an Object
Take a look at newtonsoft documentation to get more info

When you have deserialized the json string to your Rootobject, you can just pick the properties of it:
string json = "{\"foodtype\": [\"Pizza\", \"Pasta\", \"Bread\"], \"drinks\": [\"Coke\", \"Root Beer\"]}";
Rootobject rootObject = JsonConvert.DeserializeObject<Rootobject>(json);
List<string> food = rootObject.foodType.ToList();
List<string> drinks = rootObject.drinks.ToList();

Related

How to merge two json objects using JSON.NET

I have below requirement, where I need to merge two Json objects using JSON.NET.
Below is the sample code
string jsonText = #"
{
""food"": {
""fruit"": {
""apple"": {
""colour"": ""red"",
""size"": ""small""
},
""orange"": {
""colour"": ""orange"",
""size"": ""large""
}
}
}
}";
var foodJsonObj = JObject.Parse(jsonText);
var foodJsonToken = foodJsonObj.SelectToken("food.fruit") as JObject;
var bananaJson = JObject.Parse(#"{ ""banana"" : { ""colour"": ""yellow"", ""size"": ""medium""}, ""simpletype"":""simplevalue"", ""orange"":{ ""newprop"": ""newpropvalue"" } }");
var bananaToken = bananaJson as JObject;
foreach (var token1 in bananaToken)
{
**var existingTokens = foodJsonToken.Children();
foreach (var item in existingTokens)
{
var existingObject = item as JObject;
}
if (existingTokens.Contains(token1.Key))
{
foodJsonToken.Merge(token1, new JsonMergeSettings
{
MergeArrayHandling = MergeArrayHandling.Union
});
}**
else
{
foodJsonToken.Add(token1.Key, token1.Value);
}
}
json = foodJsonToken.ToString();
In the above example, I want to merge banana json into food json
above code is working without hightlighted code, if the bananajson does not have “orange” property which already in food json
if both have similar set of properties, above code is not working.
Is there any way to using linq to find existing element, if that exists, I want to merge the json else it going to update source with new properties.
Regards,
Amar
If the structure of you main json is always the same you can create two classes:
a) Main class Food with collections of fruits
b) Fruit class with fields: colour and size
You can easily add/remove any fruit from the Food class collection.
You can serialize/deserialize Food or Fruit class using NewtonSoft library.
The whole code should look like:
[DataContract]
class Food
{
[DataMember]
public ArrayList<Fruit> Fruit { get; set; }
}
[DataContract]
class Fruit
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Colour { get; set; }
[DataMember]
public string Size{ get; set; }
}
Example usage:
var sampleFoodInstanc = new Food();
sampleFoodInstance.Fruit.Add( new Fruit() { Name: "Apple", Colour: "Red", Size: "Big" } );
// serialize process
var sz = JsonConvert.SerializeObject( sampleFoodInstance );
// deserialize process
JsonConvert.DeserializeObject<Food>( sz );

Serialize and deserialize JSON object from separate classes without need to have stand-alone class?

Is it possible to form an object from two classes and then serialize it to JSON, and when deserialize it back be able to get those two objects.
say I have: an object of Student and a List<Course>
is it possible to combine these two objects in one JSON object.
I need this because building up a class for every JSON object would be very exhausting in the project I'm working on!
Is it possible to form an object from two classes and then serialize it to JSON
Yes it is possible to do this just use Merge from JObject
for example here is an example
class Student
{
public string Name { get; set; }
}
class Course
{
public string Title { get; set; }
}
var std = new Student() {Name = "foo"};
var lstCours = new List<Course>() { new Course(){Title = "math"}};
var stdJson = JsonConvert.SerializeObject(new {student=std});
var lstCoursJson = JsonConvert.SerializeObject( new{Cours= lstCours});
JObject jObjectStd = JObject.Parse(stdJson);
JObject jObjectLstCours = JObject.Parse(lstCoursJson);
jObjectStd.Merge(jObjectLstCours,new JsonMergeSettings(){MergeArrayHandling = MergeArrayHandling.Concat});
Console.WriteLine(jObjectStd.ToString());
here what you get as a merge
{
"student": {
"Name": "foo"
},
"Cours": [
{
"Title": "math"
}
]
}
to deserialize this is pretty simple with JSON.net
var stdParsed = JObject.Parse(json).Property("student").Value.ToString();
var lstCoursParsed = JObject.Parse(json).Property("Cours").Value.ToString();
var stdDes = JsonConvert.DeserializeObject<Student>(stdParsed);
var lstCoursDes = JsonConvert.DeserializeObject<List<Course>>(lstCoursParsed);
Yes, this is possible, and is actually very straightforward to do.
Say you have your two objects like this:
var student = new Student { Name = "Joe Schmoe" };
var courses = new List<Course>
{
new Course { Title = "Underwater Basket Weaving 101" },
new Course { Title = "History of Pancakes 102" }
};
On the serializing side, just use an anonymous object to combine your objects together and then serialize that:
var anon = new { Student = student, Courses = courses };
var json = JsonConvert.SerializeObject(anon, Formatting.Indented);
Here is the JSON you would get:
{
"Student": {
"Name": "Joe Schmoe"
},
"Courses": [
{
"Title": "Underwater Basket Weaving 101"
},
{
"Title": "History of Pancakes 102"
}
]
}
You can combine as many objects together as you need to in this way.
On the flip side, you can deserialize to a dynamic variable (which is a JObject behind the scenes) and then recreate your original strongly-typed objects from it using ToObject<T>().
dynamic obj = JsonConvert.DeserializeObject(json);
var student = obj.Student.ToObject<Student>();
var courses = obj.Courses.ToObject<List<Course>>();
Round-trip demo: https://dotnetfiddle.net/OKJBg2
Alternatively you can use deserialize-by-example to deserialize back to an anonymous object if you don't like the dynamic variable / JObject idea. To do that, you first create an empty anonymous object in the same shape as the JSON to use as a "template" and then pass it along with the JSON to JsonConvert.DeserializeAnonymousType:
var template = new { Student = new Student(), Courses = new List<Course>() };
var anon = JsonConvert.DeserializeAnonymousType(json, template);
Student student = anon.Student;
List<Course> courses = anon.Courses;
Demo: https://dotnetfiddle.net/Inz0r8
Serialize a KeyValuePair<Student, List<Course>> and deserialize to the KeyValuePair again.
var student = ...;
var courses = ...;
var json = JsonConvert.SerializeObject(new KeyValuePair<Student, List<Course>>(student, courses));
Then, deserialize it this way:
var pair = JsonConvert.DeserializeObject<KeyValuePair<Student, List<Course>>>(json);
var student = pair.Key;
var courses = pair.Value;
This is a workaround, but it's easy to understand, and very easy to use (compared to JObject or a class to combine them).
Just Create new Class which has those 2 objects like this
public class StudentWithCours
{
public Student student { get; set; }
public List<Course> course { get; set; }
}
after that you can serialize/deserialize the class exemplar like this
.......
StudentWithCours myObject = new StudentWithCours();
//your some logic here]
var serilizedObject = JsonConvert.SerializeObject(myObject);
var deserilizedObject = JsonConvert.DeserializeObject<StudentWithCours>(serilizedObject);
It is. This one-liner depends on the Newtonsoft NuGet package, which is popular and better than the default serializer.
var myObject = ...;
Newtonsoft.Json.JsonConvert.SerializeObject(myObject);
Documentation: Serializing and Deserializing JSON
Other possibility:
You could use the JavaScriptSerializer class (add reference to System.Web.Extensions):
using System.Web.Script.Serialization;
var json = new JavaScriptSerializer().Serialize(obj);
Other options are available here, where you can find above two answers, along with many others.
Piece of code:
public class Student
{
public string Name { get; set; }
public List<Course> Courses { get; set; } = new List<Course>();
public class Course
{
public string Name { get; set; }
public string Code { get; set; }
}
}
var student = new Student
{
Name = "Jack",
Courses = new List<Student.Course>
{
new Student.Course() {Name = "MATH", Code = "MA"},
new Student.Course() {Name = "Science", Code = "SC"}
}
};
var str = JsonConvert.SerializeObject(student);
var studentDeserialized = JsonConvert.DeserializeObject<Student>(str);
Try it out for yourself

JSON.Net Convert inner object to C# Model

I have the following JSON coming back from a remote API (I cannot modify the JSON returned)
{
"APITicket": {
"location": "SOMEVALUE",
"ticket": "SOMEVALUE"
}
}
Now using JSON.Net to convert to this to a model I have to create 2 models.
public class TicketModel
{
public string location { get; set; }
public string ticket { get; set; }
}
public class TicketContainer
{
public TicketModel APITicket { get; set; }
}
and do something like..
var myObject = JsonConvert.DeserializeObject<TicketContainer>(this.JSONResponse);
and this works well - my problem arises when I have around 50 calls to make to the API and really dont fancy creating a second 'Container' for each. Is there a way to bind the example above directly to the TicketModel?
You can do it this way:
var json = #"
{
'APITicket': {
'location': 'SOMEVALUE',
'ticket': 'SOMEVALUE'
}
}";
//Parse the JSON:
var jObject = JObject.Parse(json);
//Select the nested property (we expect only one):
var jProperty = (JProperty)jObject.Children().Single();
//Deserialize it's value to a TicketModel instance:
var ticket = jProperty.Value.ToObject<TicketModel>();
use Newtonsoft's JArray to customize ur json before deserialize
public List<APITicket> JsonParser(string json)
{
Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.Parse(json);
var list = new List<APITicket>();
foreach(var item in jArray)
{
list.Add(
new APITicket { location = item["APITicket"]["location"],
ticket = item["APITicket"]["ticket"]
}
);
}
return list;
}
Modify the JSON so it looks like this
{
"location": "SOMEVALUE",
"ticket": "SOMEVALUE"
}
and do
List<TicketModel> tickets = JsonConvert.DeserializeObject<List<TicketModel>>(this.JSONResponse);
or even
Dictionary<string, string> tickets = JsonConvert.DeserializeObject<Dictionary<string, string>>(this.JSONResponse);
so you don't need any models.

Expand dictionary to JSON fields

We have DTO class like this:
public class DTO
{
public int Number { get; set; }
public string Title { get; set; }
public Dictionary<string, string> CustomFields { get; set; }
}
I want to serialize/deserialize DTO by ServiceStack to JSON where CustomFields is expanded as DTO fields. For example
new DTO
{
Number = 42
Title = "SuperPuper"
CustomFields = new Dictionary<string, string> {{"Description", "HelloWorld"}, {"Color", "Red"}}
}
serialize to
{
"Number":42,
"Title":"SuperPuper",
"Description":"HelloWorld",
"Color":"Red"
}
How can I achieve this?
All dictionary fields must be represented as JSON object fields during serialization.
All fields of incoming JSON object that are not fields of DTO must be put to Dictionary during deserialization.
If you use the Newtonsoft library you can do this:
DTO Test = new DTO
{
Number = 42,
Title = "SuperPuper",
CustomFields = new Dictionary<string, string> { { "Description", "HelloWorld" }, { "Color", "Red" } }
};
String Json = Newtonsoft.Json.JsonConvert.SerializeObject(Test);
Json = Json.Replace("\"CustomFields\":{", "");
Json = Json.Replace("}}", "}");
The resulting json string looks like this:
{"Number":42,"Title":"SuperPuper","Description":"HelloWorld","Color":"Red"}
[Edit]
I'm not going to do ALL your work...this should get you started:
// to reconstruct the object
Newtonsoft.Json.Linq.JObject MyObject = Newtonsoft.Json.JsonConvert.DeserializeObject(Json) as Newtonsoft.Json.Linq.JObject;
// Create a new object here.
foreach( var Token in MyObject)
{
// sample
if (Token.Key == "Number")
{
// populate the fields of the new object with Token.Value
}
}

Deserialize JSON into string

How can I deserialize:
{
"data": [
{"ForecastID":8587961,"StatusForecast":"Done"},
{"ForecastID":8588095,"StatusForecast":"Done"},
{"ForecastID":8588136,"StatusForecast":"Done"},
{"ForecastID":8588142,"StatusForecast":"Pending"}
]
}
to
class RawData
{
public string data { get; set; }
}
So, I just want to have
[
{"ForecastID":8587961,"StatusForecast":"Done"},
{"ForecastID":8588095,"StatusForecast":"Done"},
{"ForecastID":8588136,"StatusForecast":"Done"},
{"ForecastID":8588142,"StatusForecast":"Pending"}
]
as value of property data of RawData's class instance.
Using Json.Net
var obj = (JObject)JsonConvert.DeserializeObject(json);
var newJson = obj["data"].ToString();
or using built-in JavaScriptSerializer
var dict = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
var newjson = new JavaScriptSerializer().Serialize(dict["data"]);
It would have made far much more sense to deserialize this JSON structure to:
public class Forecast
{
public IEnumerable<ForecastData> Data { get; set; }
}
public class ForecastData
{
public int ForecastID { get; set; }
public string StatusForecast { get; set; }
}
which is pretty trivial with the JavaScriptSerializer class that's built into the framework:
string json = "your JSON data here";
IEnumerable<ForecastData> data = new JavaScriptSerializer()
.Deserialize<Forecast>(json)
.Data;
or if you don't want to define models you could do that:
dynamic result = new JavaScriptSerializer().DeserializeObject(json);
foreach (var item in result["data"])
{
Console.WriteLine("{0}: {1}", item["ForecastID"], item["StatusForecast"]);
}

Categories

Resources