Why ajax call doesn't bind to int[] with jquery .post() - c#

Here is my ajax call:
var idsOfRecordsToBeDeleted = [];
$("#container :checked").each(
function (index) {
idsOfRecordsToBeDeleted.push($(this).attr('id'));
});
var parametersList = { param1: 123456, param2: idsOfRecordsToBeDeleted };
$.post("/Home/Index", parametersList, function (returnedData) {
alert(returnedData);
});
and there is my controller:
[Authorize]
[HttpPost]
public virtual ActionResult Index( int param1, int[] param2)
{
return null;
}
and param1 is OKAY but param2 is always null. Can you help?

You can turn traditional on for your jQuery post to allow for shallow array serialization.
jQuery.ajaxSettings.traditional = true;
var parametersList = { param1: 123456, param2: [1, 2, 3, 4] };
$.post("/Home/Index", parametersList, function (returnedData) {
alert(returnedData);
});
If you would like to apply traditional mode to only this post, you can add it with $.ajax.
var parametersList = { param1: 123456, param2: [1, 2, 3, 4] };
$.ajax({
url: "/Home/Index",
type: 'POST',
data: parametersList
traditional: true
});
Since jQuery 1.8, ajax calls will recursively serialize all objects by defaulting the traditional flag to false.
As a result, deep objects end up getting serialized into a string that represents this object structure:
param2[]=1&param2[]=2&param2[]=3&param2[]=4&=param2[]=5
ASP.NET MVC doesn't know how to handle this format. By setting traditional to true, we preserve the structure that ASP.NET MVC expects:
param2=1&param2=2&param2=3&param2=4&param2=5
EDIT:
Based on how you are building your array (attr returns a string), you will end up with an array of strings, not numbers, meaning that MVC will not deserialize your array.
You can confirm the type by inspecting the first element of idsOfRecordsToBeDeleted.
typeof(idsOfRecordsToBeDeleted[0])
Update your controller method to the following signature:
public virtual ActionResult Index( int param1, string[] param2)

Serialize the array to a string, then deserialize it on the server.
Client:
param2: [1, 2, 3, 4].join(',');
Server (Change param2 type to string instead of int[]):
int[] param2Parsed = param2.Split(',').Select(s => int.Parse(s)).ToArray();

Related

ajax object sending to controller not working

I just wanted to send list of Id numbers which collected from checkbox values. Following example code i already tried but not working mvc controller doesn't grab any Id values. Please check code bellow and tell me whats wrong i am doing here.
var _groupids = [];
$('input[class="groupids"]:checked').each(function() {
_groupids.push(this.value);
});
var ticks = {};
$.each(_groupids, function(key, value) {
ticks['Id'] = value;
});
console.log(ticks);
$.post('/MyController/Create', {
groupIds: JSON.stringify(ticks)
}).done(function(data) {
});
Model:
namespace Demo.ViewModels
{
public class Ppp
{
public int Id { get; set; }
}
}
Controller:
[HttpPost]
public ActionResult Create(List<Ppp> data)
{
//want to get ajax value in `data`
}
Note: I also tried removing JSON.stringify but still not receives any value in controller
I also tried to sending this value like this ticks = '[{"Id": 1}, {"Id": 2}, {"Id": 3}]'; and still not receives any value in controller
Many issues here:
ticks['Id'] = value uses the same key at each iteration. You are effectively overriding the value from the previous iteration.
However that wouldn't help, because you need to post a list, and you are posting an object that looks something like this: {"Id": 4}. That's not a list by any measure.
You call parameter groupIds in js, while controller expects data.
So you need to make sure your parameter names match, and the data that you send should be looking like that:
[{"Id": 1}, {"Id": 2}, {"Id": 3}]
You can do that if ticks was an array, and got inserted a new object on each iteration.

undefined error at calling method in controller from jquery ajax

I want to call a method from a controller to calculate a basic arithmetic operation. However, I get only undefined error. My code is
$("#equals3").click(
function () {
let display = $("#calculatorDisplay");
let currentValue = display.val();
$.ajax({
url:'Calculator/EvaluateExpressionAJAX',
type: 'POST',
data: { expression: currentValue },
contentType: 'application/json; charset=utf-8',
success: function (response) {
if (response.success) {
alert(response);
} else {
alert(response.responseText);
}
},
error: function (response) {
alert("error!");
}
});
});
My controller contains
public static Dictionary<string, ArithmeticOperation> EvaulationDictionary = new Dictionary<string, ArithmeticOperation> {
{ "+", (a, b) => a + b},
{ "-", (a, b) => a - b},
{ "*", (a, b) => a * b},
{ "/", (a, b) => a / b},
{ "%", (a, b) => a % b} };
[HttpPost]
public double EvaluateExpressionAJAX(string expression)
{
expression = expression.Trim();
string[] splitExpression = Regex.Split(expression, #"\s+");
double a = Convert.ToDouble(splitExpression[0]);
double b = Convert.ToDouble(splitExpression[2]);
string op = splitExpression[1];
return EvaulationDictionary[op](a, b);
}
Thanks in advance
If you would put a breakpoint in the javascript you'll probably find that MVC/WebApi returns an error page with a message like:
Invalid JSON primitive: expression
The JSON that you post is not valid, it isn't even JSON.
If you would replace that with:
data: "{ \"expression\": \"" + currentValue +"\" }",
That would post valid json to the ActionMethod.
A better option would be to create a JavaScript Object and stringify that, like this:
// create a js object before the Ajax call
let dataObj = { "expression": currentValue };
// change the data you send to this
data: JSON.stringify(dataObj),
And secondly: Take a good look at the url, I can't be sure, but if the page you rendered this from is the same controller and the index method, this probably won't work as you would expect. Change the URL to:
url:'/Calculator/EvaluateExpressionAJAX',
to make it absolute.
And finally, there are lot of possible bugs in the Action method. You can't expect users to supply 3 parts where part 1 and 3 are doubles. So there is a lot of checking missing.
And last but not least, if this is MVC, it is probably best to return ActionResult or some subtype, in this case JsonResult would suit best, from an actionmethod.

pass dict with array as value to controller

This code returns keys and values from my dict
$.map(dict, function (value, key) {
console.log(key, value);
});
output:
0 ["19,0,0,0", "23,0,0,0", "21,0,0,0", "22,0,0,0", "20,0,0,0"]
1 ["68,0,0,0", "69,0,0,0", "70,0,0,0", "71,0,0,0", "72,0,0,0", "73,0,0,0", "74,0,0,0", "75,0,0,0"]
2 ["115,0,0,0", "114,0,0,0"]
So, in my opinion it is a Dictionary <string,string[]>
I want to pass the dict to controller
$.ajax({
url: '/Home/SomeAction',
type: 'GET',
data: { categoryId: categoryId, traitValues: dict }
});
public ActionResult SomeAction(int categoryId, Dictionary<string,string[]> traitValues){...}
And here is a problem. In controller key dictionary is ok (0,1,2). But value is empty.
So how I can pass my dict from js to controller?

Pass array as query string in jquery

I have created one string array in jquery of name array[] and pushed values to it.
How can I send this array in query string?
For example window.location.href('ViewData?array');
And how can I get back the array data from query string in jquery itself ?
Please advice?
This is very easy to achieve with jQuery as it has a helper function called param().
var myData = {
name: "John Doe",
age: 23,
children: [{
name: "Jane Doe",
age: 13,
children: []
},
{
name: "John Doe Jr.",
age: 16,
children: []
}
],
}
var p = $.param(myData)
The results:
"name=John+Doe&age=23&children%5B0%5D%5Bname%5D=Jane+Doe&children%5B0%5D%5Bage%5D=13&children%5B1%5D%5Bname%5D=John+Doe+Jr.&children%5B1%5D%5Bage%5D=16"
You can use it like so:
window.location = "/MyController/MyAction?" + p;
As for getting parameters from query strings, please refer to the following question: How can I get query string values in JavaScript?
Another thing you can do is use an ajax call, this way you don't have to serialize the data yourself as it is done for you automatically.
$.ajax({
url: "/MyController/MyAction",
data: myData,
dataType: "json",
type: "POST",
success: function(data){
//'data' is your response data from the Action in form of a javascript object
}
})
I think this is what you are looking for. Let me know if I get it wrong. I copied $.parseParams from this link. You can also see working code here
(function($) {
var re = /([^&=]+)=?([^&]*)/g;
var decodeRE = /\+/g; // Regex for replacing addition symbol with a space
var decode = function (str) {return decodeURIComponent( str.replace(decodeRE, " ") );};
$.parseParams = function(query) {
var params = {}, e;
while ( e = re.exec(query) ) {
var k = decode( e[1] ), v = decode( e[2] );
if (k.substring(k.length - 2) === '[]') {
k = k.substring(0, k.length - 2);
(params[k] || (params[k] = [])).push(v);
}
else params[k] = v;
}
return params;
};
})(jQuery);
var s=["abc", "xyz", "123"];
var queryString=$.param({a:s});
console.log("object to query string: ", queryString);
console.log("query string to object: ", $.parseParams(queryString));

Array Passed to Controller Received as NULL

I'm using $.post() to post an array of integer values to my controller.
Here's how I construct my array:
var ratings = [];
$('#ratings input[name=newReviewRatings]').each(function () {
ratings.push($(this).val());
});
Here's how I'm posting it to the controller:
$.post('#Url.Action("CreateReview", "Provider")',
{
id: providerId,
ratings: ratings,
comment: comment
});
Here's the form data that gets posted:
{id=437baf29-4196-4966-88de-a8fde87ef68d&ratings%5b%5d=1&ratings%5b%5d=2&ratings%5b%5d=3&ratings%5b%5d=4&ratings%5b%5d=5&comment=Comments}
And here's my controller signature:
public ActionResult CreateReview(Guid id, int[] ratings, string comment)
{
// ....
}
That seems like that should be right, but ratings is always null. Can anyone see what I'm missing?
I also tried string[] ratings and got the same result. I also saw a suggestion to pass the array using JSON.stringify(ratings) but that didn't seem to help either.
In adition to converting the post data to json, you can also set the traditional param to true. This will cause jQuery to use the correct post format for MVC.
jQuery.ajaxSettings.traditional = true;
$.post('#Url.Action("CreateReview", "Home")',
{
id: 'GUID STRING HERE',
ratings: [1, 2, 3],
comment: 'adfef'
});
Try to specify contentType like this:
$.ajax({
url:url,
type:"POST",
data:data,
contentType:"application/json; charset=utf-8",
dataType:"json",
success: function(){
...
}
})

Categories

Resources