Appending to JSON object using JSON.net - c#

I need to serialize a JSON object that looks like this:
{
"Documents": [
{
"Title": "",
"DatePublished": "",
"DocumentURL": "",
"ThumbnailURL": "",
"Abstract": "",
"Sector": "",
"Country": [
"", "", ""
],
"Document Type": ""
}
]
}
What I'm doing is taking the data from SQL server and storing the results into an object like this:
public List<Dictionary<string, string>> GetResults()
{
int index = 0;
while (this.myReader.Read())
{
this.dataFrmDb = new Dictionary<string, string>();
for (int i = 0; i < myReader.FieldCount; i++)
{
if (myReader.GetName(i) == "Country")
{
string[] delimiter = { " _qfvcq_ " };
string text = myReader[myReader.GetName(i)].ToString();
string[] results = text.Split(delimiter, StringSplitOptions.None);
//This list stores the values for "Country".
List<string> countries = new List<string>();
for (int j = 0; j < results.Count(); j++)
{
countries.Add(results[j].ToString());
}
}
else
{
this.dataFrmDb.Add(myReader.GetName(i),
myReader[myReader.GetName(i)].ToString());
}
}
this.dictList.Add(this.dataFrmDb);
}
return this.dictList;
}
I then take this data and serialize like this:
Database connect = new Database(
System.Configuration.ConfigurationManager.AppSettings["DatabaseConnectionString"],
System.Configuration.ConfigurationManager.AppSettings["StoredProcedure"]);
List<Dictionary<string, string>> dataResults = connect.GetResults();
Dictionary<string, List<Dictionary<string, string>>> myList =
new Dictionary<string, List<Dictionary<string, string>>>();
myList.Add("Documents", dataResults);
string ans = JsonConvert.SerializeObject(myList, Formatting.Indented);
System.Console.WriteLine(ans);
I get the proper output but if you would look in the original JSON format, "Country" needs to have multiple values. I don't know how to implement that into this JSON object. How do I add a list with the "Country" values to the JSON object using JSON.net? Is there another way to go about this?

If you change dataFrmDb to be Dictionary<string, object> instead of a Dictionary<string, string>, then you can store the Countries list into it like the other values. Json.Net will then serialize it like you want.
Here is an example program which demonstrates:
class Program
{
static void Main(string[] args)
{
List<Dictionary<string, object>> dataResults = GetResults();
Dictionary<string, List<Dictionary<string, object>>> myList =
new Dictionary<string, List<Dictionary<string, object>>>();
myList.Add("Documents", dataResults);
string ans = JsonConvert.SerializeObject(myList, Formatting.Indented);
System.Console.WriteLine(ans);
}
public static List<Dictionary<string, object>> GetResults()
{
List<Dictionary<string, object>> dictList = new List<Dictionary<string, object>>();
Dictionary<string, object> dataFrmDb = new Dictionary<string, object>();
dataFrmDb.Add("Title", "An Example Document");
dataFrmDb.Add("DatePublished", DateTime.Now.ToString());
dataFrmDb.Add("DocumentURL", "http://www.example.org/documents/1234");
dataFrmDb.Add("ThumbnailURL", "http://www.example.org/thumbs/1234");
dataFrmDb.Add("Abstract", "This is an example document.");
dataFrmDb.Add("Sector", "001");
dataFrmDb.Add("Country", new List<string> { "USA", "Bulgaria", "France" });
dataFrmDb.Add("Document Type", "example");
dictList.Add(dataFrmDb);
return dictList;
}
}
Output:
{
"Documents": [
{
"Title": "An Example Document",
"DatePublished": "4/9/2013 7:25:05 PM",
"DocumentURL": "http://www.example.org/documents/1234",
"ThumbnailURL": "http://www.example.org/thumbs/1234",
"Abstract": "This is an example document.",
"Sector": "001",
"Country": [
"USA",
"Bulgaria",
"France"
],
"Document Type": "example"
}
]
}
A somewhat more straightforward way to do it is to create separate classes to hold the data, as was suggested by Joey Gennari. Json.NET can serialize those as well. The data classes would look something like this:
class Result
{
public List<Document> Documents { get; set; }
public Result()
{
Documents = new List<Document>();
}
}
class Document
{
public string Title { get; set; }
public string DatePublished { get; set; }
public string DocumentURL { get; set; }
public string ThumbnailURL { get; set; }
public string Abstract { get; set; }
public string Sector { get; set; }
public List<string> Country { get; set; }
[JsonProperty(PropertyName="Document Type")]
public string DocumentType { get; set; }
public Document()
{
Country = new List<string();
}
}
And here is the usage:
class Program
{
static void Main(string[] args)
{
Document doc = new Document();
doc.Title = "An Example Document";
doc.DatePublished = DateTime.Now.ToString();
doc.DocumentURL = "http://www.example.org/documents/1234";
doc.ThumbnailURL = "http://www.example.org/thumbs/1234";
doc.Abstract = "This is an example document.";
doc.Sector = "001";
doc.Country.Add("USA");
doc.Country.Add("Bulgaria");
doc.Country.Add("France");
doc.DocumentType = "example";
Result result = new Result();
result.Documents.Add(doc);
string json = JsonConvert.SerializeObject(result, Formatting.Indented);
System.Console.WriteLine(json);
}
}
The output for this example is exactly the same as the first.

Here is a different way to solve it with DataContractJsonSerializer. First create a class to represent the object:
[DataContract]
public class DocumentHolder
{
[DataMember(Name = "Documents")]
public Documents Document { get; set; }
}
[DataContract]
public class Documents
{
[DataMember(Name = "Title", Order = 1)]
public string Title { get; set; }
[DataMember(Name = "DatePublished", Order = 2)]
public DateTime? DatePublished { get; set; }
[DataMember(Name = "DocumentURL", Order = 3)]
public string DocumentURL { get; set; }
[DataMember(Name = "ThumbnailURL", Order = 4)]
public string ThumbnailURL { get; set; }
[DataMember(Name = "Abstract", Order = 5)]
public string Abstract { get; set; }
[DataMember(Name = "Sector", Order = 6)]
public string Sector { get; set; }
[DataMember(Name = "Country", Order = 7)]
public List<string> Country { get; set; }
[DataMember(Name = "Document Type", Order = 8)]
public string DocumentType { get; set; }
public Documents()
{
this.Country = new List<string>();
}
}
Here's how you would fill the object and serialize it:
static void Main(string[] args)
{
var documentholder = new DocumentHolder { Document = new Documents { Title = "Title 1", DatePublished = DateTime.Now, Sector = "A17", Country = new List<string> { "EN-US", "EN-GB" } } };
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(DocumentHolder));
var ms = new MemoryStream();
serializer.WriteObject(ms, documentholder);
var text = Encoding.UTF8.GetString(ms.ToArray());
}

Related

handle empty Json Array from object

I have a json object that returns two empty arrays
"subQuestions": [] and "answers": []
I have created classes for the object, but I cannot get it to work,
this is what I have so far.
Object
"questions": [
{
"questionId": "1",
"question": "Ipsum",
"helpText": null,
"questionType": "MultipleChoice",
"answerChoices": [
{
"answerChoiceId": "b2b-2.01-answer1",
"value": "Lorem",
"subQuestions": []
}
],
"answers": []
}
Classes
public class AnswerChoice
{
public string answerChoiceId { get; set; }
public string value { get; set; }
public List<object> subQuestions { get; set; }
}
public class Question
{
public string questionId { get; set; }
public string question { get; set; }
public object helpText { get; set; }
public string questionType { get; set; }
public List<AnswerChoice> answerChoices { get; set; }
public List<object> answers { get; set; }
}
public class ObjectRoot
{
public string productId { get; set; }
public List<Question> questions { get; set; }
}
var jsonBody = new ObjectRoot()
{
productId = productId,
questions = new[]
{
new Question() {
questionId = "b2b-2.01",
question ="Vad är syftet med ert engagemang hos oss?",
helpText = null,
questionType = "MultiChoise",
answerChoices = new []{
new AnswerChoice{
answerChoiceId = "",
value = "",
**HERE is what it gets tricky for me**
}
}
}
}
};
The tricky part for me is after value = "", and the subQuestion object needs to be added, have tried multiple ways but no luck.
In your classes all collections is List not array. So to make it work you need to call ToList extension method. And for empty collections just call List constructor
var jsonBody = new ObjectRoot()
{
productId = "productId",
questions = new[]
{
new Question() {
questionId = "b2b-2.01",
question ="Vad är syftet med ert engagemang hos oss?",
helpText = null,
questionType = "MultiChoise",
answerChoices = new []{
new AnswerChoice{
answerChoiceId = "",
value = "",
subQuestions = new List<object>() // empty collection
}
}.ToList(),
answers = new List<object>()
}
}.ToList()
};

Pass Object Array into Request Body

I have an object defined as follows.
public class ILT
{
public items items;
public options options;
}
public class items
{
public string course_code { get; set; }
public string session_code { get; set; }
public string date_name { get; set; }
public string date { get; set; }
public string time_start { get; set; }
public string time_end { get; set; }
public string location_name { get; set; }
public string location_address { get; set; }
public string location_country { get; set; }
public items() { }
public items(string course_code, string session_code, string date_name,
string date, string time_start, string time_end, string location_name,
string location_address, string location_country)
{
this.course_code = course_code;
this.session_code = session_code;
this.date_name = date_name;
this.date = date;
this.time_start = time_start;
this.time_end = time_end;
this.location_name = location_name;
this.location_address = location_address;
this.location_country = location_country;
}
}
I'm trying to pass the object into a RestfulAPI request body. The "items" attribute is supposed to be an array of objects.
The JSon should be formatted as follows:
{
"items": [
{
"course_id": 6,
"session_code": "my session code",
"session_name": "my session name",
"session_maximum_enrollments": 20,
"session_last_subscription_date": "2018-10-27",
"completion_type": "Evaluation",
"score_base": 100,
"date_name": "my date name",
"date": "2018-10-28",
"timezone": "America/New_York",
"time_start": "08:00:00",
"time_end": "12:00:00",
"location_name": "my location name",
"location_address": "10850 W. Park Place Suite 600, Milwaukee, WI 53225",
"location_country": "UNITED STATES OF AMERICA"
}
],
"options": {
"update_session_info": true
}
}
I'm having difficulty getting the items into an array. I'm trying to initialize the object into the request body as follows:
public bool CreateILT()
{
if (String.IsNullOrEmpty(Token))
Token = request.GetToken();
ILT classroom = new ILT
{
items = new items[0]
(
course_code = "APS_CLASSROOM",
session_code = "APS_CLASSROOM",
date_name = "August 27, 2018",
date = "2018-10-27",
time_start = "08:00:00",
time_end = "17:00:00",
location_name = "Crisis Prevention Institute",
location_address = "10850 W. Park Place Suite 600, Milwaukee, WI 53225",
location_country = "UNITED STATES OF AMERICA"
),
options = new options
{
update_session_info = true
}
};
dynamic response = request.Request_POST("/learn/v1/ilt/session/batch", Token, classroom);
if (response.data.success.ToString() == "True")
success = true;
return success;
}
Am I able to initialize an object array like this? I'm getting errors of various types when tweaking around. The above code errors out on each of the object's member's saying it does not exist in the current context.
Your class variable decleration is wrong. It stores object, not array/list of objects. And I could not see your options class. Do you have it right?
It should be declared as follows:
public class ILT
{
public List<items> items;
public options options;
}
And you should initialize it as follows:
ILT classroom = new ILT
{
items = new List<items> {
new item(
course_code = "APS_CLASSROOM",
session_code = "APS_CLASSROOM",
date_name = "August 27, 2018",
date = "2018-10-27",
time_start = "08:00:00",
time_end = "17:00:00",
location_name = "Crisis Prevention Institute",
location_address = "10850 W. Park Place Suite 600, Milwaukee, WI 53225",
location_country = "UNITED STATES OF AMERICA")
},
options = new options
{
update_session_info = true
}
};

json format output from JavaScriptSerializer

var singleItems = new List<Products>();
singleItems.Add(new Products() { product_id = 1, title = "Bryon Hetrick", price = 50 });
singleItems.Add(new Products() { product_id = 2, title = "Nicole Wilcox", price = 20 });
var serializer = new JavaScriptSerializer();
var serializedResult = serializer.Serialize(serializer);
From above example code i am getting Json output like bellow.
[{"product_id":1,"title":"Bryon Hetrick","price":50},
{"product_id":2,"title":"Nicole Wilcox","price":20}]
But my Json need one more value called- "config" also i need whole data formatted exactly like bellow. How to edit my c# code to achieve that value?
{ "products":[{"product_id":"B071H6TBM5","title":"New Iphone 5S","price":"23.45"},{"product_id":"B071DM968J","title":"Iphone 4 old","price":"23.45"}],"config":{"token":"","Site":"Us","Mode":"ListMyItem"}}
You could make a Config class with the properties you require and then a composite class with Prodcuts and Config, i.e. ProductConfig:
public class Products
{
public string product_id { get; set; }
public string title { get; set; }
public string price { get; set; }
}
public class Config
{
public string token { get; set; }
public string site { get; set; }
public string mode { get; set; }
}
public class ProductConfig
{
public List<Products> Products { get; set; }
public Config Config { get; set; }
}
You can then create/populate the ProductConfig class with the new properties.
public string SerializeProductConfig()
{
ProductConfig pc = new ProductConfig();
pc.Config = new Config { token = "DDTest", site = "US", mode = "Test Mode" };
pc.Products = new List<Products>();
pc.Products.Add(new Products() { product_id = "1", title = "Bryon Hetrick", price = "50" });
pc.Products.Add(new Products() { product_id = "2", title = "Nicole Wilcox", price = "20" });
var serializer = new JavaScriptSerializer();
return serializer.Serialize(pc);
}
and serialize the ProductConfig object using the JavaScript serializer or NewtonSoft which will give you the following JSON
{ // ProductConfig
"Products": [
{
"product_id": "1",
"title": "Bryon Hetrick",
"price": "50"
},
{
"product_id": "2",
"title": "Nicole Wilcox",
"price": "20"
}
],
"config": {
"token": "DDTest",
"site": "US",
"mode": "Test Mode"
}
}

Create JSON with dynamic using newtonsoft json.net

I am trying to create or searealize json in this format
{
"title": "Star Wars",
"link": "http://www.starwars.com",
"description": "Star Wars blog.",
"item": [
{
"title": "Episode VII",
"description": "Episode VII production",
"link": "episode-vii-production.aspx"
},
{
"title": "Episode VITI",
"description": "Episode VII production",
"link": "episode-vii-production.aspx"
}
]
}
i am trying this achieve this
dynamic o = new ExpandoObject();
o.title= "fdsfs";
o.link= "fsrg";
o.description="fdsfs";
foreach (var adata in all)
{
o.item.title="fgfd";
o.item.description="sample desc";
o.item.link="http://google.com"
}
string json = JsonConvert.SerializeObject(o);
but than here it throws exception on foreach loop on item it tells it does not contain defination for the same etc .so what i am doing wrong and how to achieve the same
That is the construction you should have to get the json you've stated. The problem with your code is that item should be actually a list of items.
public class Item
{
public string title { get; set; }
public string description { get; set; }
public string link { get; set; }
}
public class RootObject
{
public string title { get; set; }
public string link { get; set; }
public string description { get; set; }
public List<Item> item { get; set; }
}
Then you ca use this code:
dynamic o = new ExpandoObject();
o.title= "fdsfs";
o.link= "fsrg";
o.description="fdsfs";
o.item = new List<ExpandoObject>();
//although list of dynamics is not recommended as far as I remember
foreach (var adata in all)
{
o.item.Add(new Item(){
title="fgfd",
description="sample desc",
link="http://google.com" });
}
string json = JsonConvert.SerializeObject(o);
You have to create o.item to assign values into it:
dynamic o = new ExpandoObject();
var all = new object[] { new object() };
o.title= "fdsfs";
o.link= "fsrg";
o.description="fdsfs";
var items = new List<ExpandoObject>();
foreach (var adata in all)
{
dynamic item = new ExpandoObject();
item.title="fgfd";
item.description="sample desc";
item.link="http://google.com";
items.Add(item);
}
o.item = items;
string json = JsonConvert.SerializeObject(o);

How to deserialize JSON text?

I have project which uses Json data, I try deserialize a Json data like this:
[{"232":{"id":"232","reference":"022222","name":"Poire","content_title":"","content":"","pv_ttc":"230","picture_1":"","picture_2":"","picture_3":"","picture_4":"","picture_5":""}}]
If I correctly understand Json, at the beginning we have an index, then a sub-board with the name the reference the price etc.
Well, how to deserialize this text to object?
Knowing that I have my class as this:
public class productClass
{
public string id {get;set;}
public string reference { get; set; }
public string name { get; set; }
public string content_title{ get; set; }
public string content { get; set; }
public float pv_ttc{get;set;}
public string picture_1{get;set;}
public string picture_2{get;set;}
public string picture_3{get;set;}
public string picture_4{get;set;}
public string picture_5{get;set;}
public List<productClass> urlResult;
public productClass ( )
{
}
public productClass (string _id, string _reference, string _name, string _content_title, string _content, float _pv_ttc, string _picture_1, string _picture_2, string _picture_3, string _picture_4, string _picture_5)
{
id = _id;
reference = _reference;
name = _name;
content_title = _content_title;
content = _content;
pv_ttc = _pv_ttc;
picture_1 = _picture_1;
picture_2 = _picture_2;
picture_3 = _picture_3;
picture_4 = _picture_4;
picture_5 = _picture_5;
urlResult = new List<productClass> ( );
}
public void addUrl ( List<productClass> urlResult )
{
foreach ( productClass _url in urlResult )
{
urlResult.Add ( _url );
}
}
}
Thanks for help.
#sachou have you considered using JSON.Net? It is a really nice framework for .Net and you can easily de-serialize JSON strings into your C# objects. You can have a look in the documentation, but here is a simple example from the website:
Product product = new Product();
product.Name = "Apple";
product.ExpiryDate = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JsonConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "ExpiryDate": "2008-12-28T00:00:00",
// "Price": 3.99,
// "Sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//}
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);
I hope this helps.
I'd suggest you use a JSON Framework like
Newtonsoft JSON.NET
You can very easily serialize and deserialize JSON objects like this:
Product product = new Product();
product.Name = "Apple";
product.ExpiryDate = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JsonConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "ExpiryDate": "2008-12-28T00:00:00",
// "Price": 3.99,
// "Sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//}
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);
Take a closer look at Serializing/Deserializing JSON with JSON.net
Here is my example. I am using google map api as an example
I create following class corresponding to google maps
public class AddressComponent
{
public string long_name { get; set; }
public string short_name { get; set; }
public List<string> types { get; set; }
}
public class Result
{
public List<AddressComponent> address_components { get; set; }
public List<string> types { get; set; }
}
public class RootObject
{
public List<Result> results { get; set; }
public string status { get; set; }
}
Then I created this method
public string GetZipCodeBasedonCoordinates()
{
string zip = "";
string url2 = #"https://maps.googleapis.com/maps/api/geocode/json?latlng=37.423021, -122.083739&sensor=false";
System.Net.WebClient web = new System.Net.WebClient();
var result = web.DownloadString(url2);
RootObject root = JsonConvert.DeserializeObject<RootObject>(result);
var allresults = root.results;
foreach (var res in allresults)
{
foreach (var add in res.address_components)
{
var type = add.types;
if (type[0] == "postal_code")
{
zip = add.long_name;
}
}
}
return zip;
}
You can go here to see the resulting json that I have parsed
https://maps.googleapis.com/maps/api/geocode/json?latlng=37.423021,%20-122.083739&sensor=false
For more informations, see my deserialize's method :
public IEnumerator loadProducts (int cat)
{
List <int> catNoTri = new List<int> ();
catNoTri.Add (0);
gm.totalPriceItem.Clear();
isLoading = true;
WWW www = new WWW ( urlProduct );
yield return www;
Debug.Log(www.text);
string json = www.text.ToString ( );
IndexPrductClass myJson = JsonReader.Deserialize<IndexPrductClass> ( json );
foreach (productClass item in products)
{
for (int i = 0; i < products.Length; i++)
{
Debug.Log("product.productValue[i] = " + products[i].name);
}
if (firstLoad || gm.catId == 0)
{
Debug.Log ("here1");
nameProduct.Add (item.name);
Debug.Log("item.name = " + item.name);
idProduct.Add (item.id);
prixItem.Add (item.pv_ttc);
Debug.Log("item.pv_ttc = " + item.pv_ttc);
gm.totalPriceItem.Add (0);
gm.qte = new int [gm.totalPriceItem.Count];
descriptifProduct.Add (item.content);
Debug.Log(" item.content = " +item.content);
}
else if (!firstLoad)
{
Debug.Log ("here2");
nameProduct.Add (item.name);
idProduct.Add (item.id);
prixItem.Add (item.pv_ttc);
gm.totalPriceItem.Add (0);
gm.qte = new int [gm.totalPriceItem.Count];
descriptifProduct.Add (item.content);
}
}
gm.canLoad = true;
}

Categories