I'm writing an ASP.NET 3.5 app and I'm passing values from the web page to the code behind via AJAX.
The object I'm passing:
var queryData = {
'FiltrarPorTexto': false,
'Texto': "",
'FiltrarPorCategorizacion': false,
'FiltrarPorTipo': false,
'Tipo': 0,
'Pagina': 1
};
My AJAX call:
$.ajax({
type: "POST",
url: 'SDI_generararchivosbloomberg.aspx/ObtenerListadoInstrumentosJSON',
data: '{ "datosPeticion": ' + JSON.stringify(queryData) + ' }',
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(response) {
// ...
},
error: function(xhr, msg, msg2) {
// ...
}
});
My code-behind:
[WebMethod]
[ScriptMethod]
public static ObjetoRespuesta ObtenerListadoInstrumentosJSON(ObjetoFiltro datosPeticion)
{
if (datosPeticion.Pagina < 0) return new ObjetoRespuesta
{
PaginaActual = 0,
TotalPaginas = 0,
TotalRegistros = 0,
HtmlTabla = "Error: el número de página no puede ser menor a 0"
};
var elementosASaltar = (datosPeticion.Pagina - 1) * ELEMENTOS_POR_PAGINA;
var listado = bdc.GetTable<INSTRUMENTOS_BLOOMBERG>().AsQueryable();
if (datosPeticion.FiltrarPorNombre) listado = listado.Where(i => i.NEMO_INSTRUMENTO.Contains(datosPeticion.Nombre));
if (datosPeticion.FiltrarPorCategorizacion) listado = listado.Where(i => !i.ESTADO_CATEGORIZACION);
if (datosPeticion.FiltrarPorTipo) listado = listado.Where(i => i.TIPO_INSTRUMENTO == (insts.Find(r => r.Id == datosPeticion.Tipo)).Id);
var cantidadTotal = listado.Count();
if (cantidadTotal < 1) return new ObjetoRespuesta
{
PaginaActual = 0,
TotalPaginas = 0,
TotalRegistros = 0,
HtmlTabla = "Error: No se encontraron elementos"
};
if (elementosASaltar > 0) listado = listado.Skip(elementosASaltar);
listado = listado.Take(ELEMENTOS_POR_PAGINA);
return new ObjetoRespuesta
{
PaginaActual = datosPeticion.Pagina,
TotalPaginas = (cantidadTotal / ELEMENTOS_POR_PAGINA),
TotalRegistros = cantidadTotal,
HtmlTabla = GenerarTablaHtml(listado)
};
}
My problem is, some fields are not being correctly replicated in the code-behind. For example, when the queryData object is:
queryData
{...}
FiltrarPorTexto: true
Texto: "PEN"
FiltrarPorCategorizacion: false
FiltrarPorTipo: false
Tipo: 0
Pagina: 1
What gets unserialized in the code-behind is:
datosPeticion
{myNamespace.ObjetoFiltro}
FiltrarPorCategorizacion: false
FiltrarPorNombre: false
FiltrarPorTipo: false
Nombre: null
Pagina: 1
Tipo: 0
and the weird thing is, this only happens with those fields. Sending different values for FiltrarPorCategorizacion or Pagina, for example, yield the correct behavior.
Does anyone know what can I do to find the cause/fix this?
I think your myNamespace.ObjetoFiltro class is missing properties 'FiltrarPorTexto' and 'Texto' while your json object needs a 'Nombre' property.
Nevermind, this was a mistake as dumb as they can get.
For those with the same problem, make sure your JS object and the .NET object's fields have the same name.
Related
I'm trying to rewrite some data in DB using Ajax, after passing it to controller I always have the same error: System.ArgumentOutOfRangeException: Index and length must refer to a location within the string. Parameter name: length.
my Ajax code:
tab.on("click", ".edit", function (e) {
var tr = $(this).closest("tr");
var id = tr.data("id");
var fse = $(this).closest("tr").find(".FSE").text();
var field = $(this).closest("tr").find(".ui-widget");
var mon = field.find(".desc_NumM");
var monC = mon.css("background-color");
var tue = field.find(".desc_NumT");
var tueC = tue.css("background-color");
var wed = field.find(".desc_NumW");
var wedC = wed.css("background-color");
var thur = field.find(".desc_NumTr");
var thurC = thur.css("background-color");
var fri = field.find(".desc_NumF");
var friC = fri.css("background-color");
var sat = field.find(".desc_NumSa");
var satC = sat.css("background-color");
var sun = field.find(".desc_NumSu");
var sunC = sun.css("background-color");
var monVal = mon.text();
var tueVal = tue.text();
var wedVal = wed.text();
var thurVal = thur.text();
var friVal = fri.text();
var satrVal = sat.text();
var sunVal = sun.text();
$.ajax({
type: "POST",
url: "/Home/UpdateWeek",
data: {
id: id,
FSE:fse,
Monday: monVal,
Tuesday: tueVal,
Wednesday: wedVal,
Thursday: thurVal,
Friday: friVal,
Saturday: satrVal,
Sunday: sunVal,
MonColor: monC,
TueColor: tueC,
WedColor: wedC,
ThurColor: thurC,
FriColor: friC,
SatColor: satC,
SunColor: sunC
},
dataType: "JSON",
success: function (data) {
alert("Week for: " + fse + " changed!");
$('#weekEvents').load(loadWeekData());
},
error: function () {
alert("Failed, try again");
}
});
});
And here is my controller:
[HttpPost]
public JsonResult UpdateWeek(int id, EventsWeek w)
{
using (WeekEventsDBEntities db = new WeekEventsDBEntities())
{
EventsWeek ewupt = db.EventsWeeks.Where(x => x.Id == id).FirstOrDefault();
ewupt.Monday = w.Monday.Substring(0, 100);
ewupt.Tuesday = w.Tuesday.Substring(0, 100);
ewupt.Wednesday = w.Wednesday.Substring(0, 100);
ewupt.Thursday = w.Thursday.Substring(0, 100);
ewupt.Friday = w.Friday.Substring(0, 100);
ewupt.Saturday = w.Saturday.Substring(0, 100);
ewupt.Sunday = w.Sunday.Substring(0, 100);
ewupt.MonColor = w.MonColor.Substring(0, 50);
ewupt.TueColor = w.TueColor.Substring(0, 10);
ewupt.WedColor = w.WedColor.Substring(0, 10);
ewupt.ThurColor = w.ThurColor.Substring(0, 10);
ewupt.FriColor = w.FriColor.Substring(0, 10);
ewupt.SatColor = w.SatColor.Substring(0, 10);
ewupt.SunColor = w.SunColor.Substring(0, 10);
ewupt.FSE = w.FSE.Substring(0, 20);
db.SaveChanges();
}
return Json(true, JsonRequestBehavior.AllowGet);
}
debbuger always tell that there is a problem with "Substring(0, 50);". But the funny thing is, if I change "ewupt.MonColor = w.MonColor.Substring(0, 50);" to "ewupt.MonColor = w.MonColor.Substring(0, 10);" it will work ,but not like it should be. Anyway it will be no more error ans data will be passed to my DB... What I'm doing wrong here?
try checking before using subString()
if(w.MonColor.Length > 50)
{
ewupt.MonColor = w.MonColor.Substring(0, 50);
}
Because you are trying to access the string which is beyond the length of the string.
I have a google chart, that generally is very slow (over 5 minutes) and sometimes just crashes depending on the number of series I need to show. If I have one series it takes around 10 seconds, but if I add say 20 series, it will take several minutes any more than that and the browser dies.
Each series has around 8,000 rows from the JSON. I have checked and tested the code and the loop in the chart code is killing it.
My chart code is as follows:
function drawMultiLineChart() {
var section = $('#LocationNameDdl :selected').val();
var uid = '#guid';
var from = $('#dateFrom').val();
var to = $('#dateTo').val();
var parsedData = "";
var dName = "";
var colIndex = "";
var result = "";
var rowIndex = "";
$.ajax({
url: 'ProjectCharts/GetChartDataBySection',
datatype: 'json',
type: 'get',
async: false,
data: { section: section, uid: uid, from: from, to: to },
contentType: 'application/json; charset=utf-8',
success: function (d) {
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
parsedData = $.parseJSON(d);
dName = new google.visualization.DataTable();
dName.addColumn('date', 'Date');
$.each(parsedData, function (key, value) {
colIndex = dName.addColumn('number', 'Serial: ' + key);
result = $.parseJSON(value);
$.each(result, function (k, v) {
rowIndex = dName.addRow();
dName.setValue(rowIndex, 0, new Date(v.ReadingDate));
dName.setValue(rowIndex, colIndex, Number(v.ReadingValue));
});
});
var options = multiLineChartOptions();
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(dName, options);
});
},
error: function () {
alert("Error");
}
});
};
I call the JSON from the following code, this is fine and performs very quickly:
public async Task<JsonResult> GetJsonChartData(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).ToString("yyyy-MM-dd HH:mm:ss");
var g = new GetChartData(_configuration);
List<ChartDataModel> items = await Task.Run(() => g.GetChartDataFromSqlServer(serial, uid, dateFrom, dateTo));
return Json(JsonConvert.SerializeObject(items, Formatting.Indented));
}
The JSON:
[{"LoggerId":"1000651443","ReadingDate":"2018-12-05 00:03:03, "ReadingValue":"12.6", "Tooltip":"Someinfo"},
{"LoggerId":"1000651447","ReadingDate":"2018-12-05 00:04:03, "ReadingValue":"12.7", "Tooltip":"Someinfo"}]
[{"LoggerId":"1000651444","ReadingDate":"2018-12-05 00:03:05, "ReadingValue":"12.9", "Tooltip":"Someinfo"},
{"LoggerId":"1000651445","ReadingDate":"2018-12-05 00:03:07, "ReadingValue":"14.9", "Tooltip":"Someinfo"}]
[{"LoggerId":"1000651446","ReadingDate":"2018-12-05 00:03:17, "ReadingValue":"13.6", "Tooltip":"Someinfo"},
{"LoggerId":"1000651446","ReadingDate":"2018-12-05 00:04:17, "ReadingValue":"43.6", "Tooltip":"Someinfo"}]
How can I improve not only the performance but the load time?
Should I be using a different charting tool?
Can I process the data server side that will allow for increased performance?
This is my first time using JSON and I'm having a bit of trouble parsing and using it in my controller. I already tried these solutions Unable to successfully receive JSON data to .NET MVC Controller, How to receive JSON as an MVC 5 action method parameter, but none of them made it for me.
I'm retrieving some data from my html and sending the arrays through ajax to the controller in the following code:
JQuery:
var values = $('ul#values li').map(function() {
return this.textContent;
}).get()
var lines = $('ul#lines li').map(function() {
return {
Column: this.textContent,
Table: this.getAttribute("name")
};
}).get();
var columns = $('ul#lines li').map(function() {
return {
Column: this.textContent,
Table: this.getAttribute("name")
};
}).get();
var filters = $('ul#filters li.panel').map(function () {
var n = this.getAttribute("name");
var c = $(this).children()[1].textContent;
var r = $(this).find("li input:checked").map(function() {
return this.parentNode.textContent;
}).get();
if (r.length === 0)
return null;
else
return { table: n, name:c, vals: r };
}).get();
$.ajax({
type: "POST",
url: "/Home/PivotTable",
dataType: "json",
traditional: true,
data: {
indicators: values,
lines: JSON.stringify(lines) ,
columns: JSON.stringify(columns),
filters: JSON.stringify(filters)
},
success: function (data) {
alert(data.s, data.l);
}
});
And this is the form data being posted:
indicators: Taxa Mensal de inflação
lines:[{"Column":" Base","Table":"D_Base"}]
columns:[{"col":" Trimestre","table":"D_Calendario"}]
filters:[{"table":"D_PF_ClasseProdutos","name":" Código","vals":[" 22"," 23"]}]
And receiving the data in the controller where I need to access the data:
public JsonResult PivotTable(string[] indicators, Lines[] lines, object[] columns, object[] filters)
{
string sa = indicators[0];
var l = lines;
var col = columns;
var fil = filters;
var result = new { s = sa, l=l[0].Column};
return Json(result, JsonRequestBehavior.AllowGet);
}
public class Lines
{
public string Column { get; set; }
public string Table { get; set; }
}
I tried binding lines to an object, like the solution in one of the links, but got
NullRefrenceException was unhandled by usercode
While the other parameters receive the appropriate
data, but i can´t access the properties of the object.
What am I doing wrong, and how can i parse the data or bind it to an object?
You can try to use Json.NET library which allows you to serialize and deserialize.
Pass your params as string and do the following:
Lines[] m = JsonConvert.DeserializeObject<Lines>(lines);
var Javascriptxvalue= $.parseJSON($("#hdnXaxis").val());
var Javascriptyvalue= $.parseJSON($("#hdnYaxis").val());
$(document).ready(DrawMyGraph1);
function DrawMyGraph1() {
chart = new Highcharts.Chart(
{
chart: {
type: 'column',
renderTo: 'container3',
defaultSeriesType: 'area'
},
title: {
text: ''
},
subtitle: {
text: ''
},
xAxis: {
categories: Javascriptxvalue,
labels: {
enabled: false
}
},
yAxis: {
title: {
text: 'No of Patients'
}
},
credits: {
enabled: false
},
tooltip: {
formatter: function () {
return this.series.name + ' - ' + Highcharts.numberFormat(this.y, 0);
}
},
series: Javascriptyvalue
});
}
c# code
void FastMovingStocksBarChart(string date1, string date2, string selperiod, string sql)
{
DataSet dschart = new DataSet();
dschart = _obj_MIS.DoctorpatientreportChart(date1, date2, selperiod,sql);
List lstXaxis = new List();
List lstcolors = new List();
lstcolors.Add("#3366DD");
//lstcolors.Add("#FFEE22");
//lstcolors.Add("#33BBCC");
lstcolors.Add("#CC0022");
//lstcolors.Add("#FF0000");
lstcolors.Add("#339900");
lstcolors.Add("#FF7700");
lstcolors.Add("#33BBCC");
lstcolors.Add("#99EEEE");
lstcolors.Add("#6699FF");
lstcolors.Add("#9966BB");
lstcolors.Add("#99BB66");
lstcolors.Add("#FF7700");
lstcolors.Add("#FFEE22");
lstcolors.Add("#FFCBB9");
lstcolors.Add("EAEC93");
lstcolors.Add("D7FBE6");
lstcolors.Add("FFCACA");
for (int i = 0; i < dschart.Tables[0].Rows.Count; i++)
{
lstXaxis.Add(dschart.Tables[0].Rows[i]["Doctor Name"].ToString());
}
List<ChartEx> lstseries = new List<ChartEx>();
int count = 0;
for (int i = 0; i < dschart.Tables[0].Rows.Count; i++)
{
ChartEx oEx = new ChartEx();
oEx.name = dschart.Tables[0].Rows[i]["Doctor Name"].ToString();
//oEx.data.Add(Convert.ToInt32(dschart.Tables[0].Rows[i]["Patients"]));
oEx.data = new List<int>() { Convert.ToInt32(dschart.Tables[0].Rows[i]["Patients"]) };
oEx.color = lstcolors[count];
lstseries.Add(oEx);
count++;
if (count >= lstcolors.Count)
count = 0;
}
//Convert X axis data to JSON
JavaScriptSerializer oSerializer1 = new JavaScriptSerializer();
hdnXaxis.Value = oSerializer1.Serialize(lstXaxis);
//Convert Y axis data to JSON
JavaScriptSerializer oSerializer2 = new JavaScriptSerializer();
hdnYaxis.Value = oSerializer1.Serialize(lstseries);
}
I am not getting the values for "Javascriptxvalue" and "Javascriptyvalue" inside the chart function
can anyone help me
Regards
Prabhu
Presumably, 'hdnXaxis' is the id of a HiddenFieldControl server control? Perhaps the id is not what you think
var Javascriptxvalue= $.parseJSON($("#"+ <%= hdnXaxis.ClientId %>).val());
Instead of passing strings via an input, you could use server tags to directly inject the values into the page. Like this:
<%= "alert('" + MyPublicProperty + "')" %>
This should alert you to the value of the property defined in your code behind. You could then set it to a js variable like so:
<%= "var Javascriptxvalue = '" + xProperty + "';" %>
You will need to run this bit of code directly in an aspx/ascx/razor page to set the variables though, I think it's better than relying on a control with a particular id though.
I'm using tableDnD to re-order table rows, and then serialize them using "$.tableDnD.serialize()"
I want to send this to C# for processing, what's the best of doing so?
The below is an example of the serialization
pages[]=&pages[]=21&pages[]=23&pages[]=34&pages[]=37&pages[]=40&pages[]=43&pages[]=46&pages[]=49&pages[]=31&pages[]=50&pages[]=51&pages[]=52&pages[]=53&pages[]=54&pages[]=55&pages[]=56&pages[]=57&pages[]=58&pages[]=61&pages[]=65&pages[]=70&pages[]=74&pages[]=77&pages[]=78&pages[]=79&pages[]=82&pages[]=85&pages[]=88&pages[]=91&pages[]=94&pages[]=97&pages[]=100&pages[]=103&pages[]=106&pages[]=109&pages[]=112&pages[]=115&pages[]=119&pages[]=122&pages[]=123
Important Information
I tagged this as MVC but forgot to mention it. I'm using ASP.NET MVC
You can send that as-is using one of jQuery's ajax methods. I would prefer to turn it into a smaller, neater CSV string before sending it to the server as follows:
var str = 'pages[]=&pages[]=21&pages[]=23&pages[]=34&pages[]=37&pages[]=40&pages[]=43&pages[]=46&pages[]=49&pages[]=31&pages[]=50&pages[]=51&pages[]=52&pages[]=53&pages[]=54&pages[]=55&pages[]=56&pages[]=57&pages[]=58&pages[]=61&pages[]=65&pages[]=70&pages[]=74&pages[]=77&pages[]=78&pages[]=79&pages[]=82&pages[]=85&pages[]=88&pages[]=91&pages[]=94&pages[]=97&pages[]=100&pages[]=103&pages[]=106&pages[]=109&pages[]=112&pages[]=115&pages[]=119&pages[]=122&pages[]=123';
var tmpArr = str.split('&');
var pagesArr = [];
for(var i = 0;i < tmpArr.length; i++) {
var paramArr = tmpArr[i].split('=');
if(paramArr[1] != null && paramArr[1] != '') {
pagesArr.push(paramArr[1]);
}
}
alert(pagesArr); //now much prettier
//turn it into a CSV string
var pagesCsv = pagesArr.join(',');
$.ajax({
type: "POST",
url: "some.aspx",
data: pagesCsv,
success: function(msg){
alert( "Data Saved: " + msg );
}
});
Based on the example of karim79 :
var str = 'pages[]=&pages[]=21&pages[]=23&pages[]=34&pages[]=37&pages[]=40&pages[]=43&pages[]=46&pages[]=49&pages[]=31&pages[]=50&pages[]=51&pages[]=52&pages[]=53&pages[]=54&pages[]=55&pages[]=56&pages[]=57&pages[]=58&pages[]=61&pages[]=65&pages[]=70&pages[]=74&pages[]=77&pages[]=78&pages[]=79&pages[]=82&pages[]=85&pages[]=88&pages[]=91&pages[]=94&pages[]=97&pages[]=100&pages[]=103&pages[]=106&pages[]=109&pages[]=112&pages[]=115&pages[]=119&pages[]=122&pages[]=123';
var pos = null;
var index = 0;
while ((pos=str.indexOf("[]"))>-1)
{
str = str.substr(0, pos-1) + "_" + (index) + str.substr(pos+2);
index++;
}
alert(str);
$.ajax({
type: "POST",
url: "some.aspx",
data: str,
success: function(msg){
alert( "Data Saved: " + msg );
}
});
In C#
string[] keys = Request.QueryString.AllKeys;
Array.Sort(keys);
StringBuilder sb = new StringBuilder();
foreach (string key in keys)
{
if (key.IndexOf("pages_")!=-1)
{
sb.Append(Request.QueryString[key]);
}
}
// sb container the all values
You can also put everything in to one object like this:
var prm = { pages=[...], someOtherPages=[], additionalParam="", integer=1324 }
jQuery.ajax({
url: "someurl.aspx",
type: "POST",
data: {prm: JSON.stringify(prm)},
});
and parse prm on C# side by using this JSON Parser:
JObject json = JObject.Parse(Request.Form["prm"]);
JArray items = json["pages"] as JArray;
foreach (JToken item in items)
{
int i = item["type"].Value<int>(); // take an item as int
string s = item["type"].Value<string>(); // take an item as string
JArray ar = item["complex"] as JArray; // that an item as an array
}
much simplier and flexible