DataTable to JSON string for amcharts - json

I have a method in my model that queries my SQL Server database and stores the results in a datatable. Then, I am using the following method to convert that datatable into a JSON string.
public void ConvertDataTabletoJSONString(DataTable dt)
{
System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
List<Dictionary<string, object>> rows = 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]);
}
rows.Add(row);
}
JSONstring = serializer.Serialize(rows);
}
My controller looks like this:
public ActionResult getMonthlyData()
{
TDR_Monthly viewModel = new TDR_Monthly();
viewModel.getList(0);
return Json(viewModel.JSONstring, JsonRequestBehavior.AllowGet);
}
My view's javascript AmCharts.makechart dataLoader has this:
"dataLoader":
{
"url": "../TDR_MonthlyController/getMonthlyData",
"format": "json"
}
When I "test" the output of that string (by displaying the string's contents in my view, it shows properly in the browser, like so:
[{"REGION":"Atlanta", "STATE_NAME":"Alabama", "STATE":"AL", "CATEGORY_ID":"0 ", "CATEGORY":"No Group", "COUNT":100, "DEFICIENCY1":0, "DEFICIENCY2":0, "RESCIND1":0, "RESCIND2":0}]
However, when I modify the browser's URL to execute the JSON call (http://localhost:49777/Monthly/getMonthlyData) and I open the JSON file, it looks like it has a crap tone of extra spacing and characters:
"[{\"REGION\":\"Atlanta \",\"STATE_NAME\":\"Alabama \",\"STATE\":\"AL\",\"CATEGORY_ID\":\"0 \",\"CATEGORY\":\"No Group \",\"COUNT\":100,\"DEFICIENCY1\":0,\"DEFICIENCY2\":0,\"RESCIND1\":0,\"RESCIND2\":0}]
The view itself informs me that it cannot parse it
Error parsing JSON file: ../TDR_MonthlyController/getMonthlyData
Any help would be appreciated!!!

In getMontlhyData, try changing
return Json(viewModel.JSONstring);
to
return Content(viewModel.JSONstring, "application/json");
because you already have a JSON string. The Json() method is serializing it again.

Related

How to read JSON Value in ASP.NET Core controller?

How can I get value of request_id from the JSON inside my ASP.NET Core controller ?
{
"request_id": "5nRJwCgt95yfmq9qVPrzei16568823342584",
"number": "90001000000",
"price": 0.028
}
I need to assign value of request_id to string ReqID.
My controller code is as follows
public async Task<ActionResult> RequestAuthenticate()
{
var client = new RestClient("https://api.mysmsprovider.com/v1/verify");
var request = new RestRequest("",Method.Post);
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("application/x-www-form-urlencoded", "api_secret=123M&api_key=84545&code_length=4&from=NBL&to=90000001", ParameterType.RequestBody);
RestResponse response = client.Execute(request);
return Ok(response.Content);
}
ASP.NET MVC already handles this. Put the model as a param to the action method.
For example, create a model the includes the data you are interested in receiving with properties matching the JSON fields:
public class MyData {
public string request_id {get;set;}
}
And the controller
public class MyController {
public Result MyActionMethod(MyData myData) {
// now myData.request_id contains 5nRJwCgt95yfmq9qVPrzei16568823342584
// you can use it/assign it to whatever you want
var ReqID = myData.request_id;
}
}
Edit:
If you already have the JSON as a string, you can manually deserialize it into an object as follows:
var myData = Newtonsoft.Json.JsonConvert.DeserializeObject<MyData>(json);
// now myData.request_id will be the value you expect.
var ReqID = myData.request_id;
you have to parse response.Content
using Newtonsoft.Json;
string ReqID= JObject.Parse(response.Content)["request_id"].ToString();

Spring - Return Raw JSON without double serialization

I know there are other posts similar to this, but I haven't found any that help me find a solution for this particular case.
I am trying to return a HashMap<String, Object> from my Controller.
The Object part is a JSON string, but its being double serialized and not returned as a raw JSON string, thus not ending up with extra quotations and escape characters.
Controller function:
#RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public HashMap<String, Object> heartbeat(){
String streamInfo = service.getStreamInfo();
String streamCursorInfo = service.getStreamCursorInfo();
String topicInfo = service.getTopicInfo();
String greeting = "This is a sample app for using Spring Boot with MapR Streams.";
HashMap<String, Object> results = new HashMap();
results.put("greeting", greeting);
results.put("streamInfo", streamInfo);
results.put("streamCursorInfo", streamCursorInfo);
results.put("topicInfo", topicInfo);
return results;
}
Service function:
private String performCURL(String[] command){
StringBuilder stringBuilder = new StringBuilder();
try{
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process p = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while((line = reader.readLine()) != null){
stringBuilder.append(line);
}
}
catch(Exception e){
LOGGER.error(ExceptionUtils.getRootCauseMessage(e));
}
return stringBuilder.toString();
}
The cURL command I run already returns a raw JSON string. So im just trying to add it to the HashMap to be returned in the heartbeat response.
But every time I run this, my output looks like:
{
"greeting": "This is a sample app for using Spring Boot with MapR Streams.",
"streamCursorInfo": "{\"timestamp\":1538676344564,\"timeofday\":\"2018-10-04 02:05:44.564 GMT-0400 PM\",\"status\":\"OK\",\"total\":1,\"data\":[{\"consumergroup\":\"MapRDBConsumerGroup\",\"topic\":\"weightTags\",\"partitionid\":\"0\",\"produceroffset\":\"44707\",\"committedoffset\":\"10001\",\"producertimestamp\":\"2018-10-03T05:57:27.128-0400 PM\",\"consumertimestamp\":\"2018-09-21T12:35:51.654-0400 PM\",\"consumerlagmillis\":\"1056095474\"}]}",
...
}
If i return only the single string, such as streamInfo then it works fine and doesnt add the extra quotes and escape chars.
Can anyone explain what im missing or need to do to prevent this double serialization?
Instead of returning a HashMap, create an object like this:
public class HeartbeatResult {
private String greeting;
... //other fields here
#JsonRawValue
private String streamCursorInfo;
... //getters and setters here (or make the object immutable by having just a constructor and getters)
}
With #JsonRawValue Jackson will serialize the string as is. See https://www.baeldung.com/jackson-annotations for more info.
streamCursorInfo is a string, not an object => the serialization will escape the " character.
If you are able to return the object containing the data, it will work out of the box. If what you have is just a String, I suggest to serialize it to JsonNode and add it in your response
ObjectMapper objectMapper = new ObjectMapper();
JsonNode streamCursorInfo = objectMapper.readTree(service.getStreamInfo())
results.put("streamCursorInfo", streamCursorInfo);

Deserializing Json String which is stored in a string variable

I am working in VS 2015 and c#.
I have a Json String which has a list of collections, each collection represents an object,
string wsjson =
"{
"customAttributes":
[{"description":"xxxxxxx","id":11,"value":"xxxxxxx"},{"description":"xxxxxxx","id":10,"value":"xxxxxxx"}],
"location":{"account":"xxxxxxx","cabinet":"xxxxxxx"},
"misc":{"approved":false,"archived":false,"deleted":false,"echo":true,"external":false,"favorite":false,"officialLocked":false,"signed":false},
"permissions":[{"xxxxxxx":true,"xxxxxxx":false,"edit":true,"noAccess":false,"share":true,"view":true}],
"standardAttributes":{"aclStatus":"xxxxxxx","created":"\/Date(xxxxxxx)\/","createdBy":"xxxxxxx","createdByGuid":"xxxxxxx","envId":"xxxxxxx","extension":"ndws","id":"xxxxxxx","modified":"\/Date(xxxxxxx)\/","modifiedBy":"xxxxxxx","modifiedByGuid":"xxxxxxx","name":"xxxxxxx","officialVer":1,"size":4,"syncMod":xxxxxxx,"url":"xxxxxxx","versions":1}}"
DataSet wsdataSet = JsonConvert.DeserializeObject<DataSet>(wsjson);
I am getting an error. I tried to follow this (Deserializing Json String into multiple Object types) solution but I am getting error for this line as my jason data is in a string and no function to parse string.
var j = JArray.Parse(data);
Here is the visual image of the jason data.
Actual code block in my program is:
foreach (DataRow row in dataTable.Rows)
{
string wsjson = GetWorkspaceProfile(row[0].ToString());
DataSet wsdataSet = JsonConvert.DeserializeObject<DataSet>(wsjson);
DataTable wsdataTable = wsdataSet.Tables["standardAttributes"];
foreach (DataRow wsrow in wsdataTable.Rows)
{
cmbWorkspaceByCabinet.Items.Add(new KeyValuePair<string, string>(row["envId"].ToString(), wsrow["name"].ToString()));
}
}
Where GetWorkspaceProfile is a string type return function which return me JSON data as string like the image above.
public string GetWorkspaceProfile(string WorkspaceId)
{
string responseStr = "";
string url = "v1/Workspace/" + WorkspaceId + "/info";
RestType type = RestType.GET;
Boolean useXml = false;
RestRequest rr = FormRequest(type, url, useXml);
IRestResponse response;
try
{
response = executeRequest(rr);
responseStr = response.Content;
}
catch (Exception ex)
{
return null;
}
return responseStr;
}
JArray.Parse will not work, because you don't have a json array, it is an object. Also not the all values of that object are collections, for example location is also object, not a collection. You have some options to parse it
Parse root object into Dictionary
JsonConvert.DeserializeObject<Dictionary<string, string>>(wsjson)
then parse every value of the dictionary to array if value is array and to dictionary if value is object.
Create a C# class according to your json data and parse string directly into instance of that class
JsonConvert.DeserializeObject<JsonModel>(wsjson);
where JsonModel is the class you need to create.
You can use JArray and JToken to get the values you want using json path.

Converting associative array request parameters to JSON with Jackson

I am the recipient of a webhook POST that looks like this, which I have decoded for readability.
id=12345&event=this_event&payload[customer][name]=ABC Company&payload[customer][city]=New York&payload[service][name]=New Customer&payload[service][action]=New
Using Spring MVC, I can easily get this into a Map<String, Sting> that looks like this
{id=97659204, event=test, payload[customer][name]=ABC Company, payload[customer][city]=New York, payload[service][name]=New Customer, payload[service][action]=New}
I need to parse every parameter (or Map key) that starts with "payload" into a JSON object.
My desired output from parsing the request parameters that start with "payload" would look something like this
{
customer : {
name : "ABC Company",
city : "New York"
},
service : {
name : "New Customer",
action : "New"
}
}
With the final state being a call to Jackson's ObjectMapper to turn that JSON into a POJO.
Since I have no control over the data format begin sent to me, what is the best/correct option for parsing those request parameters into a JSON object?
Thanks.
I ended up writing a custom parser for the payload[][][] parameters being passed in. It uses regex matcher and then recursion to analyze each parameter, traverse a Map of 1...n Maps and then the resulting Map makes perfect JSON.
#RequestMapping(value = "/receiver", method = RequestMethod.POST)
#ResponseBody
public void receiver(#RequestParam Map<String, Object> requestBody) throws IOException {
Pattern pattern = Pattern.compile("\\[([^\\]]+)]");
Map<String, Object> payloadMap = new HashMap<>();
Matcher matcher = null;
List<String> levels = null;
for (String key : requestBody.keySet()) {
if (key.startsWith("payload")) {
matcher = pattern.matcher(key);
levels = new ArrayList<>();
while (matcher.find()) {
levels.add(matcher.group(1));
}
payloadMap = nestMap(payloadMap, levels.iterator(), (String) requestBody.get(key));
}
}
LOG.debug(mapper.writeValueAsString(payloadMap));
}
#SuppressWarnings("unchecked")
private Map<String, Object> nestMap(Map<String, Object> baseMap, Iterator<String> levels, String value) {
String key = levels.next();
if (!levels.hasNext()) {
baseMap.put(key, value);
} else {
if (!baseMap.containsKey(key)) {
baseMap.put(key, nestMap(new HashMap<String, Object>(), levels, value));
} else {
baseMap.put(key, nestMap((Map<String, Object>) baseMap.get(key), levels, value));
}
}
return baseMap;
}

read data from a json formatted object

I have a .net application in which I am getting a response data in json format. I have used the below code to get the json response.
string details= new System.Net.WebClient().DownloadString(url);
var temp = JsonConvert.DeserializeObject(details.ToString());
I have got a json format object in temp and json format string in details
I am getting an output as below from temp
{"data":
[
{"category":"Community","name":"New Page","access_token":"accesstoken_data1","perms":["ADMINISTER","EDIT_PROFILE","CREATE_CONTENT","MODERATE_CONTENT","CREATE_ADS","BASIC_ADMIN"],"id":"1234"},
{"category":"Community","name":"Page ABC","access_token":"accesstoken_data2","perms":["ADMINISTER","EDIT_PROFILE","CREATE_CONTENT","MODERATE_CONTENT","CREATE_ADS","BASIC_ADMIN"],"id":"56789"}
]
,"paging":{"next":"https:\/\/graph.facebook.com\/1100234567\/accounts?access_token=pageAccesstoken&limit=5000&offset=5000&__after_id=77786543"}
}
I need to get the category,name,access_token as key and corresponding data as values in some dictionary.
How can I achieve it?
Hope this will do the required stuffs
private Dictionary<string, object> deserializeToDictionary(string jo)
{
var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(jo);
var values2 = new Dictionary<string, object>();
foreach (KeyValuePair<string, object> d in values)
{
if (d.Value.GetType().FullName.Contains("Newtonsoft.Json.Linq.JObject"))
{
values2.Add(d.Key, deserializeToDictionary(d.Value.ToString()));
}
else
{
values2.Add(d.Key, d.Value);
}
}
return values2;
}
This was taken from the following link
How can I deserialize JSON to a simple Dictionary<string,string> in ASP.NET?
string json = #"{""key1"":""value1"",""key2"":""value2""}";
Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>
More examples: Serializing Collections with Json.NET