JSON String formed improperly using Jayrock in .NET - json

I am trying to return a JSON object from an aspx page using Jayrock.JSON.
My code for writing it out is this:
using (JsonTextWriter writer = new JsonTextWriter(Response.Output))
{
writer.WriteStartObject();
for (int i = 0; i < rdr.FieldCount; i++)
{
writer.WriteMember(rdr.GetName(i).ToString());
writer.WriteString(rdr[i].ToString());
}
writer.WriteEndObject();
}
This is inside of an rdr.Read() loop.
The outputted JSON looks like this: (though I added the line breaks manually)
{
"BugID":"1087",
"AddedBy":"",
"BugDate":"5/2/2010 9:45:34 AM",
"BugTitle":"/admin/ajax_thirdpartylog.asp",
"Classify":""
,"ErrPage":"/admin/ajax_thirdpartylog.asp",
"StoreID":"71",
"UserID":"15438",
"ErrDesc":"Type mismatch: 'formatnumber'",
"ErrDump":"*** VARIABLES DUMP ***\r\n\r\n*** Form Variables ***\r\n\r\ncalmonth : 8\r\ncalmonth2 : 8\r\nfromdate : 8/1/2009\r\ncalyear : 2009\r\ntodate : 8/31/2009\r\ncalyear2 : 2009\r\nr : 978402\r\nthirdtype : 1\r\nButton : Generate Third Party Log\r\n\r\n*** Query String Variables ***\r\n\r\n\r\n\r\n*** REPORT END ***\r\n",
"ErrLine":"74",
"DateFixed":"",
"Counter":"16",
"AssignTo":""
}
{
"BugID":"1086",
"AddedBy":"",
"BugDate":"5/1/2010 11:58:54 PM",
"BugTitle":"/admin/Charts/monthsales_s.asp",
"Classify":"",
"ErrPage":"/admin/Charts/monthsales_s.asp",
"StoreID":"402",
"UserID":"141928",
"ErrDesc":"Script timed out",
"ErrDump":"*** VARIABLES DUMP ***\r\n\r\n*** Form Variables ***\r\n\r\n\r\n*** Query String Variables ***\r\n\r\nmonth1 : 9/1/2009\r\nr : 75333803\r\n\r\n\r\n*** REPORT END ***\r\n",
"ErrLine":"0",
"DateFixed":"",
"Counter":"",
"AssignTo":""
}
I'm not really sure what I'm doing wrong, but on my page reading this JSON, when I try to do .evalJSON (using prototypejs) I get errors saying that the JSON is malformed.
Can anyone advise me what to change?

This:
"AssignTo":""
}
{
is the invalid JSON. You can a string to see if it's valid JSON at JSON Lint. I'm not sure what this should be like, but an empty object would be like this (don't need "", brackets reversed, missing comma):
"AssignTo":
{
},

The problem is that you are writing multiple JSON objects whereas what you are probably trying to do is produce a JSON array of JSON objects. Given your code snippet, I'm assuming rdr holds some IDataReader implementation like SqlDataReader. If that's true then you need to modify your code to start and end a JSON array around the outer read loop, as follows:
using (JsonTextWriter writer = new JsonTextWriter(Response.Output))
{
writer.WriteStartArray();
while (rdr.Read())
{
writer.WriteStartObject();
for (int i = 0; i < rdr.FieldCount; i++)
{
writer.WriteMember(rdr.GetName(i).ToString());
writer.WriteString(rdr[i].ToString());
}
writer.WriteEndObject();
}
writer.WriteEndArray();
}
Jayrock will automatically delimit each JSON object value with a comma (,) when inside a JSON array so now the output should resemble the following and valid JSON:
[
{
"BugID":"1087",
"AddedBy":"",
"BugDate":"5/2/2010 9:45:34 AM",
"BugTitle":"/admin/ajax_thirdpartylog.asp",
"Classify":""
,"ErrPage":"/admin/ajax_thirdpartylog.asp",
"StoreID":"71",
"UserID":"15438",
"ErrDesc":"Type mismatch: 'formatnumber'",
"ErrDump":"*** VARIABLES DUMP ***\r\n\r\n*** Form Variables ***\r\n\r\ncalmonth : 8\r\ncalmonth2 : 8\r\nfromdate : 8/1/2009\r\ncalyear : 2009\r\ntodate : 8/31/2009\r\ncalyear2 : 2009\r\nr : 978402\r\nthirdtype : 1\r\nButton : Generate Third Party Log\r\n\r\n*** Query String Variables ***\r\n\r\n\r\n\r\n*** REPORT END ***\r\n",
"ErrLine":"74",
"DateFixed":"",
"Counter":"16",
"AssignTo":""
},
{
"BugID":"1086",
"AddedBy":"",
"BugDate":"5/1/2010 11:58:54 PM",
"BugTitle":"/admin/Charts/monthsales_s.asp",
"Classify":"",
"ErrPage":"/admin/Charts/monthsales_s.asp",
"StoreID":"402",
"UserID":"141928",
"ErrDesc":"Script timed out",
"ErrDump":"*** VARIABLES DUMP ***\r\n\r\n*** Form Variables ***\r\n\r\n\r\n*** Query String Variables ***\r\n\r\nmonth1 : 9/1/2009\r\nr : 75333803\r\n\r\n\r\n*** REPORT END ***\r\n",
"ErrLine":"0",
"DateFixed":"",
"Counter":"",
"AssignTo":""
}
]

Related

vb.net - Loop throught JSON and get all data

Has anyone an idea how to loop JSON string and get all data by JSON key? I have very heavy JSON file with arrays in arrays in array.
{
"ID":"33",
"A":a,
"SUB-ID": [
{ "ID":"33"},
{ "A":"b"},
{ "SUB-ID":[] }
]
"ID":"37",
"A":a,
"SUB-ID": [
{ "ID":"38"},
{ "A":"b"},
{ "SUB-ID":[] }
]
"ID":"39",
"A":a,
"SUB-ID": [
{ "ID":"31"},
{ "A":"b"},
{ "SUB-ID":["ID":"30",SUB-ID[...]] } 'And this array in array "Sub-ID" - there may be more below each other
]
}
In Sub-Id can be infinite loop arrays....
This JSON can have lot of sub-arrays... And i need to get list of all IDs.
You do not need to loop through aka manually parse json text to create your object. Go to your nugent packages and download Newtonsoft json and add it to your project.
Now if you have a class written with that object You can now call the following:
Dim myJsonText as string = (your json text)
Dim myJsonObject as new (whatever your object name is)
MyJsonObject = JsonConvert.DeserializeObject(myJsonText, GetType(yourobjectName))
It will now create your object and now you can assign your object properties like this.
MyJsonObject.ID = 3
MyJsonObject.A=“A”
If you need to convert it back to json text you call the following:
MyJsonText = jsonConvert.SERIALIZEObject(myJsonObject)

How to properly build and append a json file from variables

I'm practising programming an application that takes user input and then outputs it to a json file.
I found a how to that explains how to do it. For the sake of length, I'm leaving out the input code and just including the json builder.
ASSIGN
uComp = "testCompany"
uEmail = "testEmail"
uName = "testName"
uAdd = "Additional"
.
DEFINE VARIABLE myObj AS JsonObject NO-UNDO.
DEFINE VARIABLE myData AS JsonObject NO-UNDO.
DEFINE VARIABLE dataParams AS JsonObject NO-UNDO.
DEFINE VARIABLE lResult AS LONGCHAR NO-UNDO
VIEW-AS EDITOR LARGE SIZE 60 BY 16.
DEFINE VARIABLE lJArray AS JsonArray NO-UNDO.
DEFINE VARIABLE lAnotherArray AS JsonArray NO-UNDO.
OUTPUT TO "output path.json".
myObj = NEW JsonObject().
dataParams = NEW JsonObject().
myObj:Add("id", "01").
dataParams:Add("Company_name", uComp).
dataParams:Add("uEmail", uEmail).
dataParams:add("uName", uName).
dataParams:add("AddInfo", uAdd).
lJArray = NEW JsonArray().
lJArray:Add(dataParams).
myObj:Add("data", lJArray).
myObj:Write(lResult, TRUE).
DISPLAY lResult.
That part works fine, but my output is like so:
lResult-----------------------------------------------------
{
"id": "01",
"data": [
{
"Company_name": "testCompany",
"uEmail": "testEmail",
"uName": "testName",
"AddInfo": "Additional"
}
]
}
how do I prevent the
lResult-----------
from being added to the file.
Secondly, I want to add additional information to the file when the code runs again so that the output will become.
{
"id": "01",
"data": [
{
"Company_name": "testCompany",
"uEmail": "testEmail",
"uName": "testName",
"AddInfo": "Additional"
},
{
"Company_name": "testCompany",
"uEmail": "testEmail",
"uName": "testName",
"AddInfo": "Additional"
}
]
}
What is the correct way to target a point in the file and add additional objects?
I though it might be something along the lines of an
append
property.
I would leave the complete JSON I/O to the JSON parser in the language. So instead of the append, I'd read in the file into a JSON object and add the additional objects/properties in memory and write back to a file.
Just an output with append won't produce value JSON. This should work:
FILE-INFORMATION:FILE-NAME = "myfile.json" .
IF FILE-INFORMATION:FULL-PATHNAME > "":U THEN DO:
myObj = CAST ((NEW ObjectModelParser()):ParseFile(FILE-INFORMATION:FULL-PATHNAME),
JsonObject) .
lJArray = myObj:GetJsonArray("data") .
END.
ELSE DO:
myObj = NEW JsonObject().
myObj:Add("id", "01").
lJArray = NEW JsonArray().
myObj:Add("data", lJArray).
END.
dataParams = NEW JsonObject().
dataParams:Add("Company_name", uComp).
dataParams:Add("uEmail", uEmail).
dataParams:add("uName", uName).
dataParams:add("AddInfo", uAdd).
lJArray:Add(dataParams).
myObj:WriteFile("myfile.json", TRUE).
how do I prevent the
lResult-----------
from being added to the file.
I suspect it's because the variable has a VIEW-AS phrase on the definition. But using the JsonObject as an object and calling the WriteFile method is the (far) better approach.

Grails: Parsing through JSON String using JSONArray/JSONObject

I have the below JSON string coming in as a request parameter into my grails controller.
{
"loginName":"user1",
"timesheetList":
[
{
"periodBegin":"2014/10/12",
"periodEnd":"2014/10/18",
"timesheetRows":[
{
"task":"Cleaning",
"description":"cleaning description",
"paycode":"payCode1"
},
{
"task":"painting",
"activityDescription":"painting description",
"paycode":"payCode2"
}
]
}
],
"overallStatus":"SUCCESS"
}
As you can see, the timesheetList might have multiple elements in it. In this ( above ) case, we have only one. So, I expect it to behave like an Array/List.
Then I had the below code to parse through it:
String saveJSON // This holds the above JSON string.
def jsonObject = grails.converters.JSON.parse(saveJSON) // No problem here. Returns a JSONObject. I checked the class type.
def jsonArray = jsonArray.timesheetList // No problem here. Returns a JSONArray. I checked the class type.
println "*** Size of jsonArray1: " + jsonArray1.size() // Returns size 1. It seemed fine as the above JSON string had only one timesheet in timesheetList
def timesheet1 = jsonArray[1] // This throws the JSONException, JSONArray[1] not found. I tried jsonArray.getJSONObject(1) and that throws the same exception.
Basically, I am looking to seamlessly iterate through the JSON string now. Any help?
1st off to simplify your code, use request.JSON. Then request.JSON.list[ 0 ] should be working

Json.Net boolean parsing issue

JObject.Parse(jsonString) is causing issue for boolean data. e.g. The json is :
{
"BoolParam": true
}
I used the following code to parse:
JObject data = JObject.Parse(str1);
foreach (var x in data)
{
string name = x.Key;
Console.Write(name + " (");
JToken value = x.Value;
Console.Write(value.Type + ")\n");
Console.WriteLine(value);
}
This print out the value as :
BoolParam (Boolean) : True
The case sensitivity causes issue as I save this json for later use. The saved json looks like
{
"BoolParam": True
}
However, when i later use it, the JObject.Parse(str) throws error as invalid Json :Unexpected character encountered while parsing value: T. Path 'BoolParam', line 2, position 15.
If I change the case from "True" to "true", it works. I dont want to add this hack to change the case when saving but is there a better way to handle this scenario.
I dont want to add this hack to change the case when saving but is
there a better way to handle this scenario.
No, you have to produce valid JSON when saving if you want to be able to later deserialize it with a JSON serializer such as Newtonsoft JSON. So fixing your saving routing is the right way to go here.
One could use anonymous types and no worry about case sensitivity of boolean type variables
public static void Main()
{
bool a = true;
JObject c = JObject.FromObject(new {BoolParam= a});
Console.WriteLine(c);
}
Output:
{
"BoolParam": true
}

Deserialize JSON using JSON.net in Wp7 application

I have this JSON format:
string jsonFormat = #"{
""Applications"": {
""data"": {
""Application named one"": [
{
""index"" : ""1"",
""name"" : ""One"",
""active"" : ""1"",
""excluded"" : ""false""
}
],
""Application named two"": [
{
""index"" : ""2"",
""forum"" : ""yes"",
}
]
}
}
}";
How exactly I can acces data childrens ? I need to retreive Application named one and Application named two - for each also the attributes with their values - the attributes are different from Application to Application.
Untill now I have:
JObject resultt= JObject.Parse(jsonFormat);
// get JSON result objects into a list
IList<JToken> results = resultt["Applications"]["data"].Children().ToList();
I looked over JSON.net documentation and could not find a solution for this...
Any help will be very usefull. Thank you.
I think you are looking for something like this:
JObject jObject = JObject.Parse(jsonFormat);
int index = jObject
.Value<JObject>("Applications")
.Value<JObject>("data")
.Value<JArray>("Application named one")
.First
.Value<int>("index");
Basically the idea is to use the Value method with the type you are expecting to retrieve a specific json element (JObject, JArray, ...) or parse a .NET value (int, string, bool, ...).