Serialized Header Detail into JSON Object Hierarchy - c#

I have two DataTable, RCPT_HEADER and RCPT_DETAIL and trying to serialize into json object hierarchy using Json.NET / C#.
I've already tried code
static JArray DataToArray(string connString, string query)
{
JArray jArray = new JArray();
try
{
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(query, conn))
{
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
int fieldcount = reader.FieldCount;
object[] values = new object[fieldcount];
reader.GetValues(values);
JObject jo = new JObject();
for (int index = 0; index < fieldcount; index++)
{
jo.Add(reader.GetName(index).ToString(), values[index].ToString());
}
jArray.Add(jo);
}
reader.Close();
}
}
}
catch (SqlException e)
{
WriteLog("[DataToArray]: " + e.Message);
}
return jArray;
}
and
static void Main(string[] args)
{
try
{
Hashtable config = getSettings(AppPath() + "mware.config");
string connString = config["cs"].ToString();
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
JsonWriter jsonWriter = new JsonTextWriter(sw);
jsonWriter.Formatting = Newtonsoft.Json.Formatting.Indented;
JObject jObject = new JObject();
JArray jArray = new JArray();
jObject.Add("RCPT_HEADER", DataToArray(connString, "SELECT * FROM RCPT_HEADER"));
jObject.Add("RCPT_DETAIL", DataToArray(connString, "SELECT * FROM RCPT_DETAIL"));
jObject.WriteTo(jsonWriter);
Console.WriteLine(jObject.ToString());
Console.ReadLine();
}
catch (Exception e)
{
WriteLog("[postJSON]: " + e.Message);
}
}
but I'm gettin output like this:
{
"RCPT_HEADER": [
{
"RECORD_ID": "1",
"ACTION_CODE": "SAVE",
"CONDITION": "Ready",
"DATE_TIME_STAMP": "9/11/2015 12:00:00 AM"
}
],
"RCPT_DETAIL": [
{
"RECORD_ID": "1",
"ACTION_CODE": "SAVE",
"CONDITION": "Ready",
"LINK_ID": "1",
"ITEM": "SKU00048700007683",
"DATE_TIME_STAMP": "9/11/2015 12:00:00 AM"
},
{
"RECORD_ID": "2",
"ACTION_CODE": "SAVE",
"CONDITION": "Ready",
"LINK_ID": "1",
"ITEM": "SKU00048700007684",
"DATE_TIME_STAMP": "9/11/2015 12:00:00 AM"
}
]
}
Actually, I would like it to return the output like this:
{
"RCPT_HEADER": [
{
"RECORD_ID": "1",
"ACTION_CODE": "SAVE",
"CONDITION": "Ready",
"DATE_TIME_STAMP": "9/11/2015 12:00:00 AM",
"RCPT_DETAIL": [
{
"RECORD_ID": "1",
"ACTION_CODE": "SAVE",
"CONDITION": "Ready",
"LINK_ID": "1",
"ITEM": "SKU00048700007683",
"DATE_TIME_STAMP": "9/11/2015 12:00:00 AM"
},
{
"RECORD_ID": "2",
"ACTION_CODE": "SAVE",
"CONDITION": "Ready",
"LINK_ID": "1",
"ITEM": "SKU00048700007684",
"DATE_TIME_STAMP": "9/11/2015 12:00:00 AM"
}
]
}
]
}
Any help would be greatly appreciated as this is the first time I have tried to use JSON.NET.

As you are using data tables, it will serialize tables this way as a JSON array of tables.
You can write your own JsonConverter in order to serialize it your way. Here is a good article.
However, in my opinion, there is another good but hacky solution: if you always have the same structure and it is not requiring too much performance, it will be easier to deserialize it again, move this object and serialize it back.
Something like this:
string json = "YOUR_JSON_RESULT";
JObject jsonObject = JObject.Parse(json);
((JObject)jsonObject["RCPT_HEADER"][0])
.Properties()
.Last()
.AddAfterSelf(new JProperty("RCPT_DETAIL", jsonObject["RCPT_DETAIL"]));
jsonObject.Remove("RCPT_DETAIL");
string jsonResult = jsonObject.ToString();
There is another one solution which is elegant and sounds proper. You use data tables but you need it to become serialized like it is not a table by implementing custom serializers or modificators. Probably, you just don't need data tables.
Do not use it if possible - use your own classes instead, so that you can describe any nesting and serialization order:
public class RcptDetail
{
public string RECORD_ID { get; set; }
/* ... */
}
public class RcptHeader
{
public string RECORD_ID { get; set; }
/* ... */
public RcptDetail RCPT_DETAIL { get; set; }
}

Related

Reformat how JSON is compiled in response

Wrote an endpoint that loops through a date range and for each new date it calls a Stored Procedure in SQL to collect data from that date. Basically the Results I'm getting are sales from each department in a specific store. This is how the JSON response looks :
{
"12/3/2022": [
{
"Department": "1101",
"Total $": 1887.30
},
{
"Department": "6021",
"Total $": 19.45
},
{
"Department": "6030",
"Total $": 247.33
}
],
"12/4/2022": [
{
"Department": "1101",
"Total $": 1942.62
},
{
"Department": "6021",
"Total $": 0.46
},
{
"Department": "6030",
"Total $": 488.13
}
]
}
But I'd really like to have this displayed with departments as the header. So, something like this :
{
"1101": [
{
"12/3/2022": 1887.30,
"12/4/2022": 1942.62
}
],
"6021": [
{
"12/3/2022": 19.45,
"12/4/2022": 0.46
}
],
"6030": [
{
"12/3/2022": 247.33,
"12/4/2022": 488.13
}
]
}
This is my code for collecting the data :
public HttpResponseMessage GetWeeklyStoreSummary(int appid, string fromDate, string endDate, string store)
{
ResponseHandler response = new ResponseHandler(this.Request);
WeeklyStoreSummaryHelper ws = new WeeklyStoreSummaryHelper();
try
{
string connectionString = GetConnectionString(appid);
WeeklyStoreSummaryDBAdapter db = new WeeklyStoreSummaryDBAdapter(connectionString);
DataSet result;
foreach (DateTime day in ws.EachDay(fromDate, endDate))
{
var currentDate = day.ToShortDateString();
result = db.GetWeeklySummary(currentDate, store);
response.AddTable(currentDate, result.Tables[0]);
}
string jsonResponse = response.GetJsonResponse();
return response.RequestCompleted(jsonResponse);
}
catch (ArgumentException a)
{
return response.BadRequest(a.Message);
}
catch (Exception e)
{
return response.GenericError(e.Message);
}
}

Modifying JSON Data Returned from C# AJAX Call

I'm doing an ajax call to retrieve JSON data returned from a query. My JSON is returning the following (accurately):
[{
"label": "",
"value": "2302"
}, {
"label": "9 - Contract set-up in EPICOR",
"value": "2280"
}, {
"label": "2 - Verify PO received",
"value": "2279"
}, {
"label": "7 - Review quote and prepare team for meeting",
"value": "2281"
}]
But I need it to actually return:
{
"options": {
"logan_dvprTasks.taskID": {
[{
"label": "",
"value": "2302"
}, {
"label": "9 - Contract set-up in EPICOR",
"value":"2280"
}, {
"label": "2 - Verify PO received",
"value":"2279"
}, {
"label": "7 - Review quote and prepare team for meeting",
"value":"2281"
}]
}
}
The code I have that generates the JSON is:
public IEnumerable<updatetasks> GetAllItems(string dvprid)
{
string stringSQL = "sqlStatement goes here";
string connString = ConfigurationManager.ConnectionStrings["loganWebConn"]
.ConnectionString;
using (SqlConnection sqlConnection = new SqlConnection(connString))
{
sqlConnection.Open();
using (SqlCommand cmd = sqlConnection.CreateCommand())
{
cmd.CommandText = stringSQL;
cmd.CommandType = CommandType.Text;
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var updatetasks = new updatetasks();
updatetasks.label = reader["taskName"].ToString();
updatetasks.value = reader["taskID"].ToString();
yield return updatetasks;
}
}
}
}
}
How can I modify my C# code to add in these two items at the start of the JSON object?
By returning the object you want instead.
Change your ajax call to this method and return it as such.
public object MyCall(string dvprid)
{
return new
{
options = new
{
logan_dvprTasks = GetAllItems(dvprid)
};
};
}
Keep in mind that . (dot) is not valid on a C# identifier, therefore I called your logan_dvprTasks.taskID simply logan_dvprTasks.
If you mean taskID to be a property of logan_dvprTasks, the resulting JSON would be
{"options":{"logan_dvprTasks":{"taskID":[...]}}}

C# JSON Data Array

I want to convert this style in C#.I want to add Contacts.How can I do it?
My Json:
[{
"Id": "1",
"Name": "emre",
"Country": "istanbul"
}, {
"Id": "2",
"Name": "semih",
"Country": "siirt"
}]
I want this style:
{
"contacts": [
{ "Id": "1",
"Name": "emre",
"Country": "istanbul"
},
{ "Id": "2",
"Name": "semih",
"Country": "siirt"
}
]
}
My web service:
String resultJSON = "";
JavaScriptSerializer js = new JavaScriptSerializer();
try{
Context.Response.Clear();
Context.Response.ContentType = "application/json";
con.Open();
cmd = new SqlCommand("Select * from City", con);
reader = cmd.ExecuteReader();
dt = new DataTable();
con.Close();
JavaScriptSerializer serializer = new JavaScriptSerializer();
List<Dictionary<String, Object>> tableRows = new List<Dictionary<string, object>>();
Dictionary<String, Object> row;
foreach (DataRow dr in dt.Rows)
{
row = new Dictionary<string, object>();
foreach (DataColumn col in dt.Columns)
{
row.Add(col.ColumnName, dr[col].ToString());
}
tableRows.Add(row);
}
resultJSON = serializer.Serialize(tableRows).ToString();
}
catch (Exception ex)
{
resultJSON = ex.Message.ToString();
}
Context.Response.Write(resultJSON);
// return resultJSON;
}
Instead of directly serializing the rows create a data model say class named Contact which has the different properties like Id , Name, country , fill it up from the database and use a library like JSON.net to serialize it .
Something similar should work for your datamodel. Please look the Serializing Collections from JSON.net
Product p1 = new Product
{
Name = "Product 1",
Price = 99.95m,
ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc),
};
Product p2 = new Product
{
Name = "Product 2",
Price = 12.50m,
ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc),
};
ProductList productList = new ProductList ();
p.Add(p1);
p.Add(p2);
string json = JsonConvert.SerializeObject(productList , Formatting.Indented);
class ProductList
{
Public List<Product> products{get;set;}
// Add method or other methods you require for your collection
}
Like Ashley John said, it would be smart to create a class representing the data json data structure. If you are lazy, or i doubt how it should look, you can use json2csharp to create the class.
Then use a json serializer of your choice, f.x. JSON.net as mentioned by Ashley J, to serialize the entire enumerable of Contacts at once. If you need the json value to be named 'contacts', you can create a containing class with field for the enumerable of contacts, so that when you serialize the containing class, you get the wanted result

Newtonsoft JSON - create JArray in JArray

I am trying to create JSON array using Newtonsoft JSON API but its giving me error. I want to achieve structure like
[
{
"id":"26",
"appsurvey":"1",
"fk_curriculumid":"70",
"status":"Completed",
"lastaccessedon":"2014-06-20 09:18:54",
"questions":[
{
"feedback":"6",
"questionid":"1"
},
{
"feedback":"8",
"questionid":"2"
},
{
"feedback":"1",
"questionid":"3"
}
],
"fk_clientid":"24",
"learnerid":"260"
}
]
I want ot add questions array for multiple time but it is giving me error
Can not add property questions to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.
Here is my code:
JArray surveytrackingA = new JArray();
/*code to add
[
{"id":"26",
"appsurvey":"1",
"fk_curriculumid":"70",
"status":"Completed",
"lastaccessedon":"2014-06-20 09:18:54"}]
*/
for (int i = 0; i < surveytrackingA.Count; i++)
{
JObject surveytrackD = (JObject)surveytrackingA[i];
string queryOne = "select * from table101 where fk_curriculumid='"
+ surveytrackD["fk_curriculumid"].ToString()
+ "' and fk_surveyid='"
+ surveytrackD["appsurvey"].ToString() + "'";
JArray questionsA = new JArray();
using (var stmt = await App.localDB.PrepareStatementAsync(queryOne))
{
while (await stmt.StepAsync())
{
JObject questionD = new JObject();
questionD.Add("questionid", stmt.GetTextAt(5));
questionD.Add("feedback", stmt.GetTextAt(6));
questionsA.Add(questionD);
}
}
surveytrackD.Add("questions", questionsA); /*error occurred here when second question array is getting inserted in surveyTrackD*/
surveytrackingA.Add(surveytrackD);
}
Can anyone please correct me. Thanks in advance.
Update:
surveytrackD have the json data,
{
"fk_clientid": "24",
"learnerid": "260",
"appsurvey": "1",
"id": "26",
"fk_curriculumid": "70",
"status": "completed",
"lastaccessedon": "2014-06-20 09:18:54"
}
You can achieve the same result (JArray in JArray) using regular C# classes and at the end serialize to JSon.
I posted a sample in Github; here a fragment of the code that produces your expected output:
var Surveys = new List<SurveytrackD>();
Surveys.Add( new SurveytrackD { id = "26", appsurvey = "1", fk_curriculumid = "70", status = "Completed", learnerid = "240" } );
Surveys.Add( new SurveytrackD { id = "27", appsurvey = "1", fk_curriculumid = "71", status = "Completed", learnerid = "241" });
foreach (var survey in Surveys)
{
survey.questions = new List<Question>();
survey.questions.Add(new Question { questionid = "1", feedback = "0" });
survey.questions.Add(new Question { questionid = "2", feedback = "1" });
}
var json = JsonConvert.SerializeObject(Surveys, Formatting.Indented);
Console.WriteLine(json);
The output is:
[
{
"fk_clientid": null,
"learnerid": "240",
"appsurvey": "1",
"id": "26",
"fk_curriculumid": "70",
"status": "Completed",
"lastaccessedon": null,
"questions": [
{
"feedback": "0",
"questionid": "1"
},
{
"feedback": "1",
"questionid": "2"
}
]
},
{
"fk_clientid": null,
"learnerid": "241",
"appsurvey": "1",
"id": "27",
"fk_curriculumid": "71",
"status": "Completed",
"lastaccessedon": null,
"questions": [
{
"feedback": "0",
"questionid": "1"
},
{
"feedback": "1",
"questionid": "2"
}
]
}
]

Create nested json with c#

I am able to create a flat serialized JSON string pretty easily with c#
My issue is I want to create a nested string like this below
[ {
title: "Yes",
id : "1",
menu: [ {
title: "Maybe",
id : "3",
alert : "No",
menu: [ {
title: "Maybe Not",
id : "8",
alert : "No",
menu: []
} ]
} ]
},
{
title: "No",
id : "2",
menu: []
}]
Any help would be great
Are you using MVC 3? - Do something like:
return Json(myObectWithListProperties, JsonRequestBehavior.AllowGet);
I use this to return complex C# objects that match the structure of the JavaScript objects I want.
e.g.:
var bob = new {
name = "test",
orders = new [] {
new { itemNo = 1, description = "desc" },
new { itemNo = 2, description = "desc2" }
}
};
return Json(bob, JsonRequestBehavior.AllowGet);
gives:
{
"name": "test",
"orders": [
{
"itemNo": 1,
"description": "desc"
},
{
"itemNo": 2,
"description": "desc2"
}
]
}
EDIT: A bit more nesting for fun:
var bob = new {
name = "test",
orders = new [] {
new { itemNo = 1, description = "desc" },
new { itemNo = 2, description = "desc2" }
},
test = new {
a = new {
b = new {
something = "testing",
someOtherThing = new {
aProperty = "1",
another = "2",
theThird = new {
bob = "quiteDeepNesting"
}
}
}
}
}
};
return Json(bob, JsonRequestBehavior.AllowGet);
gives:
{
"name": "test",
"orders": [
{
"itemNo": 1,
"description": "desc"
},
{
"itemNo": 2,
"description": "desc2"
}
],
"test": {
"a": {
"b": {
"something": "testing",
"someOtherThing": {
"aProperty": "1",
"another": "2",
"theThird": {
"bob": "quiteDeepNesting"
}
}
}
}
}
}
Try using
using System.Web.Script.Serialization;
//Assumed code to connect to a DB and get data out using a Reader goes here
Object data = new {
a = reader.GetString(field1),
b = reader.GetString(field2),
c = reader.GetString(field3)
};
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
string json = javaScriptSerializer.Serialize(data);
This is built-in and saves you the work of serializing to JSON yourself!
This example assumes you are getting data from a database using some sort of reader, and it then constructs the object you want to serialize using an anonymous class. Your anonymous class can be as simple or complex as you need it to be and the JavaScriptSerializer will handle transforming it to JSON. This approach is also useful because you can easily control the JSON property names it will create in the JSON.
using System.Web.Script.Serialization;
var strNJson = new
{
to = "hello",
notification = new
{
title = "textTitle",
body = "bodyText"
}
};
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
string json = javaScriptSerializer.Serialize(strNJson);
{ "to":"hello",
"notification": {
"title":"titleText",
"body":"bodyText"
}
}
You can make use of the ExpandoObject under the System.Dynamic namespace.
Here is a small snippet for achieving your solution:
dynamic parameters = new dynamic[2];
parameters[0] = new ExpandoObject();
parameters[0].title = "Yes";
parameters[0].id = "1";
parameters[0].menu = new dynamic[1];
parameters[0].menu[0] = new ExpandoObject();
parameters[0].menu[0].title = "Maybe";
parameters[0].menu[0].id = "3";
parameters[0].menu[0].alert = "No";
parameters[0].menu[0].menu = new dynamic[1];
parameters[0].menu[0].menu[0] = new ExpandoObject();
parameters[0].menu[0].menu[0].title = "Maybe Not";
parameters[0].menu[0].menu[0].id = "8";
parameters[0].menu[0].menu[0].alert = "No";
parameters[0].menu[0].menu[0].menu = new dynamic[0];
parameters[1] = new ExpandoObject();
parameters[1].title = "No";
parameters[1].id = "2";
parameters[1].menu = new dynamic[0];
string json = JsonConvert.SerializeObject(parameters, Formatting.Indented);
Console.WriteLine(json);
Here is the work in fiddle
Note: There are other ways to achieve this, but I have been using this approach.

Categories

Resources