How to parse JSON and iterate over it? - c#

How can I iterate over the images in JSON of following format? Length of images collection can be arbitrary. Can I manipulate it to make it a list, or what options do I have to parse this?
images: {
0: {
filename: "image1.jpg"
},
1: {
filename: "image2.jpg"
},
2: {
filename: "image3.jpg"
},
}

One possible solution would be to create a dynamic representation of your json:
dynamic jsonData = JsonConvert.DeserializeObject(#"{
images: {
0: {
filename: ""image1.jpg""
},
1: {
filename: ""image2.jpg""
},
2: {
filename: ""image3.jpg""
}
}
}");
foreach(var item in jsonData["images"])
{
//Do something
}

If you have a read of this SO question, you'll notice that JSON.NET is a recommended library to use for situations like this.
You could try using the DataContractJsonSerializer to create objects from JSON input, but when I tried it just now, I couldn't get it to work with a collection of items in the JSON string.

You can do this with vanilla javascript like this:
for (objectName in data["images"]) {
html += data["images"][objectName]["filename"] + "<br />"
}
Full HTML file example below
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="result"></div>
<script type="text/javascript">
var data = {
"images": {
"0": {
"filename": "image1.jpg"
},
"1": {
"filename": "image2.jpg"
},
"2": {
"filename": "image3.jpg"
}
}};
var html = '';
for (objectName in data["images"]) {
html += data["images"][objectName]["filename"] + "<br />"
}
document.getElementById("result").innerHTML = html;
</script>
</body>
</html>

I ended up figuring it out - although may not be best practice it worked in this case
var imageHoldingList = new List<VehicleImagesModel>();
var connectionResponse = JsonConvert.DeserializeObject<dynamic>(results);
var jImage = connectionResponse["response"]["vehicles"]["images"].Children();
foreach (var image in jImage)
{
var h = new VehicleImagesModel
{
Filename = image.First.filename.ToString(),
Caption = image.First.caption.ToString()
};
imageHoldingList.Add(h);
}

Related

How to format google chart x axis in DateTime format from C#

I'm developing a web site in MVC 5 and I'm using google chart to display some chart for my data. I'm using the line chart for a data which have a value and a date. Something like the follow:
class ChartData
{
public double Value { get; set; }
public DateTime Date { get; set; }
};
In my controller I have a request handler to generate the data for the chart:
public JsonResult GenerateChartData(int id)
{
List<ChartData> list = new List<ChartData>();
// some code to populate the list
return Json(list, JsonRequestBehavior.AllowGet);
}
Everything works fine except that the X axis which should show the date time sequence is formatted in the wrong way. The looks like absolute time not in readable date format.
see the chart output
thanks for any answer
google charts will accept dates in a couple ways,
which depend on how the data table, used to draw the chart, is loaded...
1)
if you're using one of the following methods to load the data table...
addRow(), addRows(), arrayToDataTable()
the date will need to be a javascript date object,
created using the new keyword,
any valid constructor will work
new Date();
new Date(value);
new Date(dateString);
new Date(year, month[, date[, hours[, minutes[, seconds[, milliseconds]]]]]);
2)
if using json to load the data table directly...
var data = new google.visualization.DataTable(jsonData);
the following string format can be used...
which needs to be a string value (wrapped in quotes), without the new keyword...
"Date(Year, Month, Day, Hours, Minutes, Seconds, Milliseconds)"
where Month is zero-based
"Date(2017, 4, 16)" // <-- 5/16/2017
This is the way to load the data inside a java script. But in my case the data are generate in json format by a request to the controller. I post the code of my page
#model BDF.RemoteData.Data.TagData
#{
ViewBag.Title = "Chart";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>[[[Grafico]]]</h2>
<input type="hidden" id="idInput" data-value="#ViewBag.id" />
<input type="hidden" id="idSystem" data-value="#ViewBag.system" />
<input type="hidden" id="idStart" data-value="#ViewBag.start" />
<input type="hidden" id="idEnd" data-value="#ViewBag.end" />
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1",
{
packages: ["corechart"]
});
google.setOnLoadCallback(drawChart);
function drawChart()
{
var id = $("#idInput").data("value");
var system = $("#idSystem").data("value");
var start = $("#idStart").data("value");
var end = $("#idEnd").data("value");
$.ajax(
{
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: '#Url.Action("GenerateChartData")',
data:
{
id: id,
system: system,
start: start,
end: end
},
type: "GET",
error: function (xhr, status, error)
{
var err = eval("(" + xhr.responseText + ")");
toastr.error(err.message);
},
beforeSend: function ()
{
},
success: function (data)
{
HistDashboardChart(data);
return false;
},
error: function (xhr, status, error)
{
var err = eval("(" + xhr.responseText + ")");
toastr.error(err.message);
},
complete: function ()
{
}
});
return false;
}
//This function is used to bind the user data to chart
function HistDashboardChart(data)
{
$("#Data_Chart").show();
var dataArray = [
['Date', 'Value']
];
$.each(data, function (i, item)
{
dataArray.push([item.Date, item.Value]);
});
var data = google.visualization.arrayToDataTable(dataArray);
var options = {
legend:
{
position: 'bottom',
textStyle:
{
color: '#f5f5f5'
}
},
colors: ['#34A853', 'ff6600', '#FBBC05'],
backgroundColor: '#454545',
hAxis:
{
title: 'Time',
titleTextStyle:
{
italic: false,
color: '#00BBF1',
fontSize: '20'
},
textStyle:
{
color: '#f5f5f5'
}
},
vAxis:
{
baselineColor: '#f5f5f5',
title: 'Values',
titleTextStyle:
{
color: '#00BBF1',
italic: false,
fontSize: '20'
},
textStyle:
{
color: '#f5f5f5'
},
viewWindow:
{
min: 0,
format: 'long'
}
},
curveType: 'function',
};
var chart = new google.visualization.LineChart(document.getElementById('Data_Chart'));
chart.draw(data, options);
return false;
};
</script>
<div id="Data_Chart" style="width: 100%; height: 500px"> </div>
As you can see the job id done by the request url: '#Url.Action("GenerateChartData")'
Then the returned data are pushed into an array the the code
var dataArray = [
['Date', 'Value']
];
$.each(data, function (i, item)
{
dataArray.push([item.Date, item.Value]);
});
In this case I'm assuming that item.Date is already in a datetime format but maybe I have to format it in a special way.
The output of the console.log(item.Date) is the following:
/Date(1494937128000)/
/Date(1494937133000)/
/Date(1494937138000)/
/Date(1494937143000)/
/Date(1494937148000)/
/Date(1494937153000)/
/Date(1494937158000)/
/Date(1494937163000)/
Which looks strange I think, doesn't it?
Ok I got it. Reading this article made everything clear
How to parse JSON to receive a Date object in JavaScript?
I modified the java script code inside my page in the following way:
var dataArray = [
['Date', 'Value']
];
$.each(jsondata, function (i, item) {
var d = new Date(parseInt(item.Instant.substr(6)));
dataArray.push([d, item.Value]);
});
Now it works perfectly

not able to decode the string from C# HttpUtility.JavaScriptStringEncode in javascript

I am generating html through C#
myStr = "<span class='red'>September 1980</span><br /><div>abcdef\nhijklm</div>";
shtml = "<span class='red' title='<pre>" + HttpUtility.JavaScriptStringEncode(myStr, false) + "</pre>' id='" + jc.FirstOrDefault().UserId + "'>" + content + "</span>" + after;
... snip snip ...
<%= shtml %>
And my jquery script for initializing qtip is:
$('[title!=""]').each(function(){
$(this).qtip({
hide: {
fixed: true, delay: 300
}, show: 'mouseover',
position: {
my: 'top center',
at: 'bottom center',
viewport: $(window),
adjust: {
method: 'shift shift'
, screen: true
}
}, style: {
classes: 'qtip-light', // Inherit from preset style
tip: 'topCenter'
}
});
});
Now the tooltip is showing:
\u003cspan class=\u0027abcd\u0027 title=\u0027September 05, 2013 12:06\u0027\u003e\u003ci
How can I render the html in tooltip?
this has been eating my time and brains... please help!
Note: please read the following before marking this question as duplicate:
I searched all the related posts, but none of the soutions worked for me. My use case is different as I am using qtip to show the string generated by javascriptstringencode.
I could not find any built in function to decode the data which is encoded using HttpUtility.JavaScriptStringEncode. So I created a JS function after some research in various sites.
String.prototype.replaceAll = function(str1, str2, ignore) {
return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g, "\\$&"), (ignore ? "gi" : "g")), (typeof(str2) == "string") ? str2.replace(/\$/g, "$$$$") : str2);
}
function decodeJs(encodedString) {
var decodedString = encodedString;
decodedString = decodedString.replaceAll("\\u0026", "&");
decodedString = decodedString.replaceAll("\\u0027", "\'");
decodedString = decodedString.replaceAll("\\u003c", "<");
decodedString = decodedString.replaceAll("\\u003e", ">");
return decodedString;
}
function replaceText() {
$("*").each(function() {
if (!$(this).children().length) {
$(this).text(decodeJs($(this).text())).val(decodeJs($(this).val()));
}
});
}
$(document).ready(replaceText);
$("html").ajaxStop(replaceText);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Pass data to Javascript function

I am using the following snippet to populate a Google Chart-
<script type="text/javascript">
google.load("visualization", "1", { packages: ["corechart"] });
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses'],
['2004', 1000, 400],
['2005', 1170, 460],
['2006', 660, 1120],
['2007', 1030, 540]
]);
var options = {
title: 'Company Performance'
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
This works a treat and creates a line graph as desired.
However I wish to pass data to this function from my code behind -
protected void Page_Load(object sender, EventArgs e)
{
string JsonString = "{'res':[{'category':'A','count':17167},{'category':'B','count':18183},{'category':'C','count':17972},{'category':'D','count':18539}]}";
Jobj = JObject.Parse(JsonString);
// extract values from Json
foreach (var response in Jobj["res"])
{
string category= (string)response["category"];
int count = (int)response["count"];
// put values into format that can be passed to the javascript function
}
}
And then use is like -
function drawChart() {
var data = google.visualization.arrayToDataTable([<%=Data Values%>]);
Where count and category are the X and Y axis values and the 17167,18183 etc are the points on the graph.
However clearly the aforementioned syntax is incorrect, how can I modify the function to accept my Json data?
Since you already have the JSON string, there's no point in parsing it, then re-serializing it. Just inject it directly, and use Javascript to map into the Google Viz format:
function drawChart() {
var json = <%= JsonString %>;
var arr = [ ["Category", "Count"] ];
json.res.forEach(function(item) {
arr.push( [ item.category, item.count ] );
});
console.log(JSON.stringify(arr)); // [["Category","Count"],["A",17167],["B",18183],["C",17972],["D",18539]]
var data = google.visualization.arrayToDataTable(arr);
}
Here is demo of the data-mapping part.

How to load JSON data into SlickGrid with Razor MVC-4

I am new to jquery, slick grid and razor. I have gone through SlickGrid examples and am able to load static data into a SlickGrid. Now I am trying to load JSON data from MSSQL into my SlickGrid. I have seen a few examples online, but I believe I am missing something not mentioned in those examples.
Here is what I have code.
SlickGridProducts.js
var grid;
var columns = [
{ id: "ProductID", name: "ProductID", field: "ProductID", width: 50 },
{ id: "ItemDesc", name: "ItemDesc", field: "ItemDesc", width: 200 },
{ id: "DivName", name: "DivName", field: "DivName", width: 50 },
{ id: "DeptDesc", name: "DeptDesc", field: "DeptDesc", width: 75 },
{ id: "ClassDesc", name: "ClassDesc", field: "ClassDesc", width: 100 },
{ id: "SubClassDesc", name: "SubClassDesc", field: "SubClassDesc", width: 100 }
];
var options = {
editable: true,
enableAddRow: true,
enableCellNavigation: true,
asyncEditorLoading: false,
autoEdit: false
};
$(function () {
var slickdata = [];
$.getJSON("/Products/GetSlickGridData", function (items) {
for (var i = 0; i < items.length; i++) {
slickdata[i] = {
ProductID: items[i].ProductID,
ItemDesc: items[i].ItemDesc,
DivName: items[i].DivName,
DeptDesc: items[i].DeptDesc,
ClassDesc: items[i].ClassDesc,
SubClassDesc: items[i].SubClassDesc
};
}
});
grid = new Slick.Grid("#myGrid", slickdata, columns, options);
grid.setSelectionModel(new Slick.RowSelectionModel());
grid.setActiveCell(0, 0);
})
Products/Index.cshtml
#model IEnumerable<JQGrid.Models.Product>
#{
ViewBag.Title = "Index";
}
<link href="#Url.Content("~/Content/slick.grid.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.8.2.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.event.drag.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/SlickGrid/slick.core.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/SlickGrid/slick.grid.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/SlickGridProducts.js")" type="text/javascript"></script>
<h2>Index</h2>
<div id="myGrid" style="width:800px;height:300px;"></div>
ProductsController.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using JQGrid.Models;
namespace JQGrid.Controllers
{
public class ProductsController : Controller
{
private ProductPickerEntities db = new ProductPickerEntities();
//
// GET: /Products/
public ActionResult Index()
{
return View(db.Products.ToList());
}
...
public JsonResult GetSlickGridData()
{
var slickGridData = db.Products.ToList();
return Json(slickGridData, JsonRequestBehavior.AllowGet);
}
}
}
If I add a breakpoint in JsonResult GetSlickGridData() and watch slickGridData, I see that it is populated with all the items I want in my slickgrid.
With this all I get is a blank white box for my slick grid. I figure the problem is in my js where I am filling slickdata, but not sure what to fix.
**** Revision *****
I found one of my issues, but the slickgrid is still blank. My issue was the json result being returned was too large. So I modified my ProductsController.cs code for right now to say
public JsonResult GetSlickGridData()
{
var slickGridData = db.Products.ToList();
var jsonResult = Json(slickGridData, JsonRequestBehavior.AllowGet);
jsonResult.MaxJsonLength = int.MaxValue;
return jsonResult;
}
This resolves the maxlength error although I had thought this was resolved in MVC-4.
Did you check the browser console for errors?
You're initializing grid.setSelectionModel(new Slick.RowSelectionModel());, but have not included a reference to it.
It is slick.rowselectionmodel.js and is typically under the Plugins folder.

Get Rendered HTML from a page in ASP.NET

Hello I have a html page (twitter.html) with the following script
<script type="text/javascript" charset="utf-8" src="http://widgets.twimg.com/j/2/widget.js"></script>
<script type="text/javascript">
function getParameterByName(name)
{
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.search);
if(results == null)
return "";
else
return decodeURIComponent(results[1].replace(/\+/g, " "));
}
var TwitterCount = getParameterByName('TwitterCount');
var TwitterHandleName = getParameterByName('TwitterHandleName');
new TWTR.Widget({
version: 2,
type: 'profile',
rpp: TwitterCount,
interval: 30000,
width: 272,
height: 'auto',
theme: {
shell: {
background: '#ffffff',
color: '#000000'
},
tweets: {
background: '#ffffff',
color: '#005A8C',
links: '#000000'
}
},
features: {
scrollbar: false,
loop: false,
live: false,
behavior: 'all'
}
}).render().setUser(TwitterHandleName).start();
</script>
If I access the page
http://localhost/twitter.html?TwitterHandleName=billgates&TwitterCount=3
I am able to see the last 3 tweets.
What I want is to do an http posting on this page from my aspx page. Below code returns only the script tags etc instead of rendered html. My question is how to get the rendered html of a page?
HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create("http://localhost/twitter.html?TwitterHandleName=billgates&TwitterCount=3);
loHttp.Timeout = 30000;
loHttp.UserAgent = "Twitter";
HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse();
//Encoding enc = Encoding.GetEncoding(1252); // Windows default Code Page
StreamReader loResponseStream = new StreamReader(loWebResponse.GetResponseStream());
string htmlCode = loResponseStream.ReadToEnd();
loWebResponse.Close();
loResponseStream.Close();
I understand it's using a prebuilt javascript widget, but could you move it server-side using a twitter wrapper like https://github.com/danielcrenna/tweetsharp (available from NuGet) or http://linqtotwitter.codeplex.com/?
You can try to open that url into frame on your web page and get html from them using javascript.

Categories