Extra Square Brackets Being Added in array to JSON ouput - c#

I have found that when converting my arrays to JSON, there are extra square brackets that are preventing the data from being parsed.
I make an AJAX call which prepares the data server side. The C# processes the data and turns it into an array of arrays for Google Charts to process.
It is all dynamic, so I have no idea how many arrays there will be, hence I cannot hardcode the arrays and I cannot loop the client side as the performance is shocking.
I don't think the JSON parser in the JavaScript is the issue, it is in the C# I have written.
I have added two JSON links, one is the output, the other is the expected output.
My C# is:
public List<object[]> CreateJsonMultiChartData(string serial, string guid, string datefrom, string dateto)
{
var serials = _context.RawData.Where(x => x.ProjectGuid == guid).Select(x => x.SerialNumber).Distinct().ToList();
var projectUid = guid;
var from = datefrom;
var to = dateto;
//Method to return data
var g = new GetChartDataSprocs(_context, _configuration);
List<object> chartData = new List<object>();
var arrays = new List<object[]>();
foreach (var s in serials)
{
var data = g.GetChartDataFromSqlServer(s, projectUid, from, to);
foreach (var item in data)
{
var year = Convert.ToDateTime(item.ReadingDate).Year;
var month = Convert.ToDateTime(item.ReadingDate).Month;
var day = Convert.ToDateTime(item.ReadingDate).Day;
var hour = Convert.ToDateTime(item.ReadingDate).Hour;
var minute = Convert.ToDateTime(item.ReadingDate).Minute;
var second = Convert.ToDateTime(item.ReadingDate).Second;
var date = "new Date(" + year + "," + month + "," + day + "," + hour + "," + minute + "," + second + ")";
chartData.Add(
new ChartTestModel
{
ReadingDate = date,
ReadingValue = item.ReadingValue
});
};
arrays.Add(new[] { chartData });
}
return arrays;
}
My AJAX response is:
public JsonResult GetMultiChartData(string serial, string uid, string from, string to)
{
var dateFrom = Convert.ToDateTime(from).ToString("yyyy-MM-dd HH:mm:ss");
var dateTo = Convert.ToDateTime(to).AddMinutes(1).ToString("yyyy-MM-dd HH:mm:ss");
var g = new GetChartData(_context, _configuration);
var items = g.CreateJsonMultiChartData(serial, uid, dateFrom, dateTo);
//var dsItems = JsonConvert.DeserializeObject(items);
// return items;
return Json(JsonConvert.SerializeObject(items, Formatting.Indented));
}
My AJAX call is:
$.ajax({
url: 'ProjectCharts/GetMultiChartData',
datatype: 'json',
type: 'get',
async: false,
data: { section: section, uid: uid, from: from, to: to },
contentType: 'application/json; charset=utf-8',
success: function (d) {
parsedData = $.parseJSON(d);
var data = new google.visualization.arrayToDataTable([
{ label: 'Date', id: 'ReadingDate', type: 'date' }, // Use object notation to explicitly specify the data type.
{ label: 'Data', id: 'ReadingValue', type: 'number' }, [parsedData]]);
var chart = new google.visualization.LineChart(document.getElementById('chart'));
var options = multiLineChartOptions();
chart.draw(data, options);
},
error: function () {
alert("Error");
}
});
The output is at:
Current JSON Ouput
The expected output is:
Expected JSON Output

Related

Multiple JSON objects for multi series chart

I am using the Google.DataTable wrapper by #zoranmax. I can get a single line chart to work fine. What I want to do is display multiple lines.
When I return the JSON to AJAX call to create the chart I am told that I have no columns in the table.
The C# return produces a list of string that is indexed, so for each series, there is a 0,1,2 etc.
Here is an example of the JSON output JSON Output, there are 20 of these arrays that are returned from the C# code in one hit to AJAX call.
As you can see the JSON validates, but it just won't work.
The AJAX call:
$.ajax({
url: 'ProjectCharts/GetMultiChartData',
datatype: 'json',
type: 'get',
async: false,
data: { section: section, uid: uid, from: from, to: to },
contentType: 'application/json; charset=utf-8',
success: function (d) {
parsedData = $.parseJSON(d);
console.log(parsedData);
var data = new google.visualization.DataTable(parsedData);
var chart = new google.visualization.LineChart(document.getElementById('chart'));
var options = multiLineChartOptions();
chart.draw(data, options);
},
error: function () {
alert("Error");
}
});
The C# part:
public string CreateJsonMultiChartDataTable(string serial, string guid, string datefrom, string dateto)
{
var serials = _context.LogTagRawData.Where(x => x.ProjectGuid == guid).Select(x => x.SerialNumber).Distinct().ToList();
var projectUid = guid;
var from = datefrom;
var to = dateto;
List<string> multiDt = new List<string>();
try
{
foreach (var s in serials)
{
var data = GetChartDataFromSqlServer(s, projectUid, from, to);
var dt = new Google.DataTable.Net.Wrapper.DataTable();
dt.AddColumn(new Google.DataTable.Net.Wrapper.Column(Google.DataTable.Net.Wrapper.ColumnType.Datetime, "Date", "Date"));
dt.AddColumn(new Google.DataTable.Net.Wrapper.Column(Google.DataTable.Net.Wrapper.ColumnType.Number, "Data", "Data"));
foreach (var item in data)
{
Google.DataTable.Net.Wrapper.Row r = dt.NewRow();
r.AddCellRange(new Google.DataTable.Net.Wrapper.Cell[]
{
new Google.DataTable.Net.Wrapper.Cell(Convert.ToDateTime(item.ReadingDate)),
new Google.DataTable.Net.Wrapper.Cell(item.ReadingValue)
});
dt.AddRow(r);
}
multiDt.Add(dt.GetJson());
}
}
catch (Exception ex)
{
var m = ex.Message;
}
var sb = new StringBuilder();
sb.Append("[");
foreach(var i in multiDt)
{
sb.Append("[");
sb.Append(i);
sb.Append("],");
}
sb.Append("]");
string xx = sb.ToString();
int yy = xx.LastIndexOf(',');
xx = xx.Remove(yy, 1);
return xx;
}
JSON call from AJAX
public JsonResult GetMultiChartData(string serial, string uid, string from, string to)
{
var dateFrom = Convert.ToDateTime(from).ToString("yyyy-MM-dd HH:mm:ss");
var dateTo = Convert.ToDateTime(to).AddMinutes(1).ToString("yyyy-MM-dd HH:mm:ss");
var g = new GetChartData(_context, _configuration);
var items = g.CreateJsonMultiChartDataTable(serial, uid, dateFrom, dateTo);
var deserialisedJsonData = JsonConvert.DeserializeObject(items);
return Json(JsonConvert.SerializeObject(deserialisedJsonData, Formatting.Indented));
}

How can highlight a date in jQuery?

I cannot dynamically highlight the date in calendar, only static dates highlight if I do:
eventDates[new Date('01/09/2018')] = new Date('01/09/2018')
Here is my code:
$(function() {
// An array of dates
var eventDates = [];
$.ajax({
type: "GET",
url: "#Url.Action("
GetEvents ", "
Home ")",
dataType: "json",
data: "",
success: function(data) {
$.each(data, function(i, val) {
var dd = CTD(val.Date); //CTD means convert into date
eventDates[i] = dd;
});
}
});
// convert in date
function CTD(d) {
var date = new Date(parseInt(d.substr(6)));
var month = date.getMonth() + 1;
return date.getDate() + "/" + month + "/" + date.getFullYear();
}
//eventDates[new Date('01/09/2018')] = new Date('01/09/2018');
// datepicker
$('#datepicker').datepicker({
beforeShowDay: function(date) {
var highlight = eventDates[date];
if (highlight) {
return [true, "event", 'Tooltip text'];
} else {
return [true, '', ''];
}
}
});
});
Then in the DatePicker, you are searching in the array indexes, so you will not find the date. To find the date you need to use the indexOf() method and you need to format the DatePicker date in the same format that you saved in the array:
var month = date.getMonth() + 1;
date = date.getDate() + "/" + month + "/" + date.getFullYear();
var highlight = eventDates.indexOf(date);
Instead of repeating the code to format the date, you extract the formatting code from your CTD() function into a new function:
// convert in date
function CTD(d) {
var date = new Date(parseInt(d.substr(6)));
return FD(date);
}
// format date
function FD(d) {
return d.getDate() + "/" + (d.getMonth() + 1) + "/" + d.getFullYear();
}
And finally, you want to make sure that the code for the DatePicker will only run after the Ajax result comes back, so put in a function and call it from the success of the Ajax:
$(function() {
$.ajax({
type: "GET",
url: "#Url.Action("GetEvents", "Home")",
dataType: "json",
data: "",
success: function(data) {
var eventDates = []; //An array of dates
$.each(data, function(i, val) {
eventDates[i] = CTD(val.Date); //CTD means convert into date
});
HighlighEvents(eventDates);
}
});
// convert in date
function CTD(d) {
var date = new Date(parseInt(d.substr(6)));
return FD(date);
}
// format date
function FD(d) {
return d.getDate() + "/" + (d.getMonth() + 1) + "/" + d.getFullYear();
}
// datepicker
function HighlighEvents(eventDates) {
$('#datepicker').datepicker({
beforeShowDay: function(date) {
var highlight = eventDates.indexOf(FD(date));
if (highlight > -1) {
return [true, "event", 'Tooltip text'];
} else {
return [true, '', ''];
}
}
});
}
});

Get Json Data from WebMethod to Application

I wanted to get Json data from web method.In here i wanted to get News & Speaker both data but here only working News only.(Unable to get Speaker )
Here is my Stored Procedure
ALTER procedure [dbo].[LoadDayEvents]
#Date date
as
begin
select News,Speaker from Eventstbl
where DateToBePublished = CONVERT(date, #Date)
end
Here is my Web Method
[WebMethod, ScriptMethod]
public static string SelectEventDate(string date)
{
string News= "";
string Speaker = "";
try
{
SqlCommand comld = new SqlCommand("LoadDayEvents", conDB);
comld.CommandType = CommandType.StoredProcedure;
comld .Parameters.Add("#Date", SqlDbType.Date);
comld .Parameters["#Date"].Value = DateTime.Parse(date).Date;
if (conDB.State == ConnectionState.Closed)
conDB.Open();
News = comld .ExecuteScalar().ToString();
Speaker = comld .ExecuteScalar().ToString(); // Thisone is not working
}
catch (Exception ee) { }
finally { conDB.Close(); }
return News;
}
Here i use Ajax/Json to get it
<script type="text/javascript">
$(document).ready(function () {
var urinews = '<%= ResolveUrl("WebMethods.aspx/SelectEventDate") %>';
var localtime = new Date();
var today = localtime.getFullYear() + '/' + (localtime.getMonth() + 1) + '/' + localtime.getDate();
$.ajax({
type: "POST",
url: urinews,
data: "{ date: '" + today + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function (msg) {
$("#daily_news_Selection").append("<p>" + msg.d + "</p>");
},
error: function (x, e) {
}
});
});
</script>
You could return custom class
var newsAndSpeaker = new NewsAndApeaker() { News = News, Speaker = Speaker}; //or define a custom class that has these two properties
return newsAndSpeaker;
On Javascript, you can access the two variables using
msg.d.News //news
msg.d.Speaker
Or, you could return a list of string
var newsAndSpeaker = new List<string>() { News, Speaker}; //or define a custom class that has these two properties
return newsAndSpeaker;
On Javascript, you can access the two variables as in like a array
msg.d[0] //mews
msg.d.[1] //speaker
If your question is why your second property is not getting populated, then title seems to be wrong

iterate through JSOn result

I have a WebMethod being called from ajax, trying to iterate through the returned data. The data being returned is "{ BusinessTypeID = 2 }". I'm trying to figure out how to just get the value 2?
//Function called from ajax
[System.Web.Services.WebMethod]
public static string[] GetTerminalBusinessTypes(string terminalID)
{
DataClassesDataContext db = new DataClassesDataContext();
List<string> results = new List<string>();
try
{
var terminalBusinessTypes = (from bt in db.BusinessTypes
join obt in db.OxygenateBlenderBusinessTypes on bt.BusinessTypeID equals obt.BusinessTypeID
where obt.OxygenateBlenderID == Convert.ToInt32(terminalID)
select new
{
bt.BusinessTypeID
}).ToList();
for (int i = 0; i < terminalBusinessTypes.Count(); i++)
{
results.Add(terminalBusinessTypes[i].ToString());
}
}
catch (Exception ex)
{
}
return results.ToArray();
}
The ajax function:
function PopulateTerminalBusinessTypes(terminalID) {
$.ajax({
type: "POST",
url: "OxygenateBlenderCertificationApplication.aspx/GetTerminalBusinessTypes",
data: "{'terminalID':" + terminalID + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
var targetValue = data.d;
var items = $('#cblTerminalBusinessType input:checkbox');
$.each(targetValue, function (key, targetValue) {
alert(data[index].BusinessTypeID);
});
}
})//end ajax
}
When your web service returns the json value, asp.net wraps in an object, with the key being d and the value being your json string. Review this link for more info.
You have to parse the value string into a json object. Using jQuery (v1.4.1 or higher):
jQuery.parseJSON(targetValue);
To be honest I cannot see where your "index" is defined.
Shouldn't the alert line read
$each(targetVale, function(key, item) {
// on second look, this wont work as you are converting toString()
alert(targetValue[key].BusinessTypeId)
// this should
alert(item)
});
You could also throw a debugger; line above the alert and see the values being traversed.
You may want to try returning a JSON string from C#:
public static **string** GetTerminalBusinessTypes(string terminalID)
...
var oSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string sJSON = oSerializer.Serialize(results);
return sJSON;

Linq to SQL get multiple columns

I am developing an asp.net MVC web app in which I am using Linq to Sql for getting the results from database through jquery and ajax. My model has following code
public IEnumerable<string> getComments(long problemID)
{
var comment = from c in _objectModel.Comments
where c.ProblemID == problemID
select new { c.EmpID, c.CommentText, c.Time }.ToString();
return comment;
}
and my controller has following code
public string GetComments(string problemid)
{
List<string> collection = _discussionRepository.getComments(Convert.ToInt32(problemid)).ToList();
string comments = null;
foreach (string item in collection)
{
comments += item + "\n";
}
return comments;
}
and in my view contains
$("#btnPostComment").click(function () {
var strdata = {
problemID: $("#problemID").val(),
commentText: $("#_1").val(),
empID: $("#empID").val(),
agree: 0,
disagree: 0
};
$.ajax({
type: "POST",
url: "<%= Url.Action("PostComment", "Discussion") %>",
data: strdata,
error: function(msg){
alert("error" + msg);
},
success: function (msg) {
var id = { problemid : $("#problemID").val()};
$.ajax({
type: "GET",
url: "<%= Url.Action("GetComments", "Discussion") %>",
data: id,
error: function(msg){
alert("error2" + msg);
},
success: function (msg) {
$("#commentdiv").html(msg);
}
});
}
});
and I am getting the following result in my asp page
{ EmpID = 1, CommentText = sss, Time = 1/27/2012 2:20:49 AM } { EmpID = 1, CommentText = aaa, Time = 1/27/2012 2:46:07 AM } { EmpID = 1, CommentText = aaa, Time = 1/27/2012 2:50:23 AM } { EmpID = 1, CommentText = Munazza, Time = 1/27/2012 2:58:29 AM } { EmpID = 1, CommentText = Jawad, Time = 1/27/2012 3:00:51 AM } { EmpID = 1, CommentText = xx, Time = 1/28/2012 11:56:59 AM } { EmpID = 1, CommentText = ss, Time = 1/28/2012 12:35:00 PM }
I want to get the result without braces and without properties i.e 1 ss 1/27/2012
Regards
The problem is that you're calling ToString on the anonymous type. Does your existing Comment model class contain too much data? If not, you can just use:
public List<Comment> GetComments(long problemID)
{
return _objectModel.Comments.Where(c => c.ProblemID == problemID)
.ToList(); // Force evaluation
}
You'd then change your controller to convert this List<Comment> into AJAX which the Javascript could understand.
If you really only want strings without properties, you could just change your original code to:
public IEnumerable<string> GetComments(long problemID)
{
var query = from c in _objectModel.Comments
where c.ProblemID == problemID
select new { c.EmpID, c.CommentText, c.Time };
return query.AsEnumerable() // Do the rest locally
.Select(c => string.Format("{0} {1} {2"}, c.EmpID,
c.CommentText, c.Time));
}
You should also change your controller code to either use String.Join or a StringBuilder - as otherwise you're going to have an O(n2) problem due to repeated string concatenation...
Looking at your client-side code it seems you're expecting formatted html from the ajax call, but you're simply returing ToString (as Jon Skeet says).
If this is your intent then you should format the string into valid HTML, but it would be better to return the data in json format and turn it into HTML client-side.

Categories

Resources