IActionResult not returning the view - c#

So, i call trhough Ajax an IActionResult to go to another view and the IActionResult executes entirely except that it doesn't return the view.
Here is the code of the action result, it just take some products and search for their prices on the database and then sums them. And it executes perfectly. I changed the code a little to some lines to show me the values of each variable in the console and it works fine. The only problem is that when it suppose to show the view in the browser, nothing happens
[HttpPost]
public IActionResult Cart(List<int[]> carrito){
var productsToBuy = selectProductsByID(carrito);
var detallesOrden = new List<OrderDetailModel>();
int sumaTotal = 0;
for(int i = 0; i<carrito.Count; i++){
var detalle = new OrderDetailModel{
idProduct = carrito[i][0],
cantidad = carrito[i][1],
subTotal = productsToBuy[i].precio * carrito[i][1]
};
sumaTotal += detalle.subTotal;
}
var orden = new OrderModel{
estado = 0,
sumaTotal = sumaTotal
};
ViewBag.ProductsToBuy = productsToBuy;
ViewBag.DetallesOrden = detallesOrden;
ViewBag.Orden = orden;
return View();
}
This is the function which i use to call the actionresult it sends an array with the products id and their quantities
function goToCart(){
showCart();
var target = '#Url.Action("Cart", "Home")';
$.ajax({
type: 'POST',
data:{
carrito: carrito
},
url: target,
success: function(result){
},
error: function(result){
alert('error');
}
});
}
What am i doing wrong? I'll appreciate any kind of help.
Sorry for the combinnation of english and spanish.

Related

JQuery loop slowing Google Chart performance

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?

Receive JSON in MVC controller

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);

Refesh ViewData after call Jquery function MVC

I have to refresh the items of two ListBox after a dropdownlist value change.
The data of the ListBoxes is in the ViewData and i call a action controller from jquery function, but the ViewData after the call have the same data.
Here is the code:
$(document).ready( function () {
$('#users').change(function () {
var selectedValue = $('#users').val();
$.post('#Url.Action("GruposUsuario", "Grupos")', { usersId: selectedValue }, function () {
var gruposAsig = JSON.parse('#Html.Raw(Json.Encode(ViewData["gruposAsignados"]))');
var gruposDisp = JSON.parse('#Html.Raw(Json.Encode(ViewData["gruposDisponibles"]))');
$('#gruposAsignados').empty();
$('#gruposAsignados').addItems(gruposAsig);
$('#gruposDisponibles').empty();
$('#gruposDisponibles').addItems(gruposDisp);
});
});
$.fn.addItems = function (grupos) {
return this.each(function () {
var list = this;
$.each(grupos, function (index, itemData) {
var option = new Option(itemData.Text, itemData.Value);
list.add(option);
});
});
};
});
And the Controller Code:
[HttpPost]
public ActionResult GruposUsuario(string usersId)
{
AllUsers();
GruposAsignados(int.Parse(usersId));
//GruposDispobibles(int.Parse(usersId));
return Json("Usuario");
}
void GruposAsignados(int usersId)
{
var grupos = new BL.Grupos().GruposAsignados(usersId);
List<SelectListItem> list = new List<SelectListItem>();
foreach (var grupo in grupos)
{
SelectListItem selectList = new SelectListItem()
{
Text = grupo.GroupName,
Value = grupo.GroupsId.ToString()
};
list.Add(selectList);
}
ViewData["gruposAsignados"] = list as IEnumerable<SelectListItem>;
}
How can i refesh the ViewDatas after the event?
Razor code is parsed on the server before it is sent to the view. Your use of #Html.Raw(...) assigns vales to gruposAsig and gruposDisp that are the initial values of the ViewData properties (inspect the source when you first render the page).
In any case you method GruposAsignados() only returns a string with the value "Usuario". If you want to return json data to update the options in two dropdownlists, then you controller method should be
[HttpGet] // its a GET
public ActionResult GruposUsuario(string usersId)
{
var gruposAsignados= new BL.Grupos().GruposAsignados(usersId).Select(g => new
{
ID = g.grupo.GroupsId;
Name = g.GroupName;
}
var gruposDisponibles = // another query
return Json(new { Asignados = gruposAsignados, Disponibles = gruposDisponibles, JsonRequestBehavior.AllowGet);
}
Then the script should be
var asignados = $('#gruposAsignados'); // cache it
var disponibles = $('#gruposDisponibles');
$.getJSON('#Url.Action("GruposUsuario", "Grupos")', { usersId: selectedValue }, function (response) {
if(response) {
asignados.empty();
// or asignados.empty().append($('</option>').val('').text('-Please select-'));
$.each(response.Asignados, function(index, item) {
asignados.append($('</option>').val(item.ID).text(item.Name));
});
disponibles.empty();
$.each(response.Disponibles, function(index, item) {
disponibles.append($('</option>').val(item.ID).text(item.Name));
});
}
});
Side note: There is no need to create IEnumerable<SelectListItem>. The browser has no knowledge of what a C# class is and you just returning extra unnecessary data (the values of the Selected, Group and Disabled properties) which are never used.

WebMethod is returning name of variable, not the array

This is driving me crazy... as part of another issue I've been working on ajax transfers to my mvc4 web app.
I've been working with this as an example: http://www.codeproject.com/Articles/692793/Introduction-to-Knockout-js-and-CRUD-Operations-in
The model is as follows:
public class ColorList
{
public int? ID;
public string ColorName;
}
The controller function is as follows:
[WebMethod]
public ColorList[] GetAssignedColors(string szUserRecID)
{
int Rec = Convert.ToInt32(szUserRecID);
var query = (from t in db.tblColors
join c in db.tblUser on t.fkColorID equals c.pkColorID
where t.fkRecID == Rec
select new ViewModels.ColorList()
{
ColorName = c.szColorName,
ID = t.ColorID
}).OrderBy(c => c.ColorName);
//var q = query.ToArray(); // if I break and view q, the array exists
return query.ToArray();
}
Not sure this matters but here's my Ajax method:
$.ajax({
type: "POST",
url: '#Url.Action("GetAssignedColors", "EditColors")',
data: { szUserRecID: RecID },
success: function (results) {
var colors = $.map(results.d, function (item) {
return new Color(item)
});
self.CurrentColors(colors);
},
error: function (err) {
alert(err.status + " : " + err.statusText);
}
})
if I watch fiddler the response my code provides is (in text view):
"MyApps.ViewModels.ColorList[]"
Not the array of colors as I am expecting.
Why is the function returning the variable name as an array instead of the array itself?
I've played around with this, but my ajax call doesn't seem to interpret the json response... However, the data shows in this instance but get a 200/ok with seemingly unusable data in my web page.
[HttpPost]
public JsonResult GetAssignedColors(string szUserRecID)
{
int Rec = Convert.ToInt32(szUserRecID);
var query = (from t in db.tblColors
join c in db.tblUser on t.fkColorID equals c.pkColorID
where t.fkRecID == Rec
select new ViewModels.ColorList()
{
ColorName = c.szColorName,
ID = t.ColorID
}).OrderBy(c => c.ColorName);
//var q = query.ToArray(); // if I break and view q, the array exists
return Json(query.ToArray(), JsonRequestBehavior.AllowGet);
}
Since formatting didn't work in the comments this is what worked; results didn't have the data necessary but "data" did.
success: function (data) {
var colors = $.map(data, function (item) {
return new Color(item)
});
The webpage I was working off of had:
success: function (result) {
var colors = $.map(result.d, function (item) {
return new Color(item)
});
The actual working method was:
success: function (data) {
var colors = $.map(data, function (item) {
return new Color(item)
});
I did not use the [webmethod] per Robert's wisdom and used the json response.
The final / working function was:
[HttpPost]
public JsonResult GetAssignedColors(string szUserRecID)
{
int Rec = Convert.ToInt32(szUserRecID);
var query = (from t in db.tblColors
join c in db.tblUser on t.fkColorID equals c.pkColorID
where t.fkRecID == Rec
select new ViewModels.ColorList()
{
ColorName = c.szColorName,
ID = t.ColorID
}).OrderBy(c => c.ColorName);
//var q = query.ToArray(); // if I break and view q, the array exists
return Json(query.ToArray());
}
Note the removal of JsonRequestBehavior.AllowGet
thanks Robert!

cant get the array to my actionresult

im trying to get the values of all the checked checkboxes and post those values(integer) to an action result, the problem is i get an empty array at the controller side ...
my jquery code is as follow:
function getIds() {
var idList = new Array();
var loopCounter = 0;
//find all the checked checkboxes
$("input:checked").each
(
function() {
//fill the array with the values
idList[loopCounter] = $(this).val();
loopCounter += 1;
}
);
//Send the list off
alert(idList);
var postData = { values: idList };
$.post("/Admin/Delete/", postData);
}
my controller side code is following
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(Int32[] values)
{
try
{
// TODO: Add delete logic here
return RedirectToAction("NewSubDashboard");
}
catch
{
return View();
}
}
there is no problem with the posting but im gettin an empty array at the controller side...
Shouldn't your $.post be:
$.post("/Admin/Delete/", postData);
Since postData:idList is probably undefined.
i extracted the values from httpcontext as
HttpContext ctx = System.Web.HttpContext.Current;
string[] ValArr = ctx.Request.Params.GetValues(0);

Categories