In MVC 4, how do you pass a JavaScript array in the View to a function in the Controller with AJAX?
This doesn't seem the work:
$.ajax(
{
type: "POST",
url: "../Home/SaveTable",
data: { function_param: countryArray }
});
Problem is, countryArray is a global array in the JavaScript View and I've check that it has elements in it before being passed. However, when the saveTable function receives the array, the function says it received a null string[] array.
I only know that passing arrays from the Controller to the View, you serialize complex data types with return Json(data, JsonRequestBehavior.AllowGet); and then de-serialize it by setting it to a "var" variable.
So I probably have to do it for this as well, but how to?
Edit 1:
Here is the shortened version of the SaveTable function:
public string SaveTable(string[] function_param)
{
if (function_param != null && function_param > 0)
{
//some code
return "Success";
}
//The following code will run if it's not successful.
return "There must be at least one country in the Region.";
//Yeah it's always returning this b/c function_param is null;
}
You need to set traditional: true when serializing arrays.
$.ajax({
type: "POST",
traditional: true,
url: "../Home/SaveTable",
data: { function_param: countryArray }
});
Found this good explanation on what traditional: true does: https://stackoverflow.com/a/5497151/2419531
EDIT:
If you don't want to use traditional: true, you can pass the data as string using JSON.stringify and specifying the contentType:
$.ajax({
type: "POST",
url: "../Home/SaveTable",
contentType: 'application/json',
data: JSON.stringify({function_param: countryArray}),
});
You should use on your controller:
public string SaveTable(object[] function_param)
{
//some code
}
Should do the work, it's for future users.
your Ajax :
$.ajax({
type: "POST",
url: "../Home/SaveTable",
contentType: 'application/json',
data: {function_param: JSON.stringify(countryArray)},
});
in your controller:
using Newtonsoft.Json;
public string SaveTable(string function_param)
{
dynamic func_param = JsonConvert.DeserializeObject(function_param)
}
then you will be able to do a foreach in your controller.
Related
I'm using ajax to send an int64 and a string from a month selector to my server-side, but my variable is always null or 0.
JS:
function deleteConta(id) {
var data = $("#monthSelector").val();
var params = {
id: id,
dataAtual: data
};
$.ajax({
type: "POST",
url: '/Contas/ContaView?handler=Delete',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(params),
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (partialReturn) {
$("#partial").html(partialReturn);
}
});
}
C#:
public PartialViewResult OnPostDelete([FromBody] long id, string dataAtual)
{
contaDTO.Remove(id, contaDTO.Database, contaDTO.ContaCollection);
dataCorrente = DateTime.ParseExact(dataAtual, "yyyy-MM", null).AddMonths(1);
contas = BuscarContasUsuarioMes(User.Identity.Name, dataCorrente);
return Partial("_PartialContas", contas);
}
I already checked with debugger and my variables are ok and filled with value expected (One test was like {id: 50, dataAtual: '2023-01'}
Checked a lot of forums, but Couldn't figure out how to make this thing work.
By declaring the number parameter with [FromBody] you tell ASP.NET Core to use the input formatter to bind the provided JSON (or XML) to a model. So your test should work, if you provide a simple model class.
Have you tried to remove it and sending value to the action?
—- UPDATE ——
Try this
function deleteConta(id) {
var data = $("#monthSelector").val();
$.ajax({
type: "POST",
url: '/Contas/ContaView?handler=Delete',
data: { id: id, dataAtual: data },
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (partialReturn) {
$("#partial").html(partialReturn);
}
});
}
I originally wrote the call as a GET but found a limitation with the length of the URI. Ideally, the call will take an object and turns it into a JSON format string, then sends it to a controller which will encrypt that string. The controller will send back a true/false if it succeeded.
My problem with POST, once it reaches the controller, the data parameter set from the ajax is null.
Here is the ajax/js:
var encActionURL = '#Url.Action("Encrypt", "Home")';
$.ajax({
url: encActionURL,
type: "POST",
contentType: "application/json; charset=utf-8;",
dataType: "json",
async: true,
traditional: true,
data: { jsonDoc: JSON.stringify(jsonDataFile) },
success: /*OnSuccess*/ function (result) {
// DO STUFF;
}
});
Here is the controller:
[HttpPost]
public bool Encrypt(string jsonDoc)
{
return serverConnection.Encrypt();
}
Note that, when I simply change the type to 'GET', it works great but when the form gets too long, it throws a 414 status error.
Most of the fixes found that I seem to have is the 'application/json'. I've also set ajax to traditional.
After going through a rabbit-hole of security tokens and validating forms, it wasn't any of that... this might be a solution for anyone using ASP.NET Core 2.1 MVC (5?) or just in general. Could have been a syntax mistake, return type mistake, or a combination.
New Ajax
$.ajax({
url: encActionURL,
type: "POST",
data: { 'jsonDoc': JSON.stringify(jsonDataFile) }, // NOTICE the single quotes on jsonDoc
cache: false,
success: /*OnSuccess*/ function (result) {
// DO STUFF;
}
});
New Controller
[HttpPost]
public ActionResult EncryptJSON(string jsonDoc) // Switch to ActionResult, formerly JsonResult
{
return Json(serverConnection.Encrypt());
}
I have a jquery ajax script like following
$.ajax({
type: "POST",
url: "Main/receive", // the method we are calling
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ 'p':$("#txtname").val() }),
dataType: "json",
success: function (result) {
alert('Yay! It worked!');
// Or if you are returning something
},
error: function (result) {
alert('Oh no zzzz:('+result.responseText);
}
});
And I am calling to Controller action method. The data is sending to the controller's action method and I am also receiving data from the controller. But the data that I am receiving is inside the error function of jquery ajax.
I want it to be inside the success function.
Why my success function is not getting called.
Following is my controller's action method,
[HttpPost]
public string receive(string p)
{
ViewBag.name = p;
return p;
}
The reason for the error is that you have specified that the returned data type be json (in the line dataType: "json",) but you method returns text. You have 2 options.
Change the controller method to return json using return Json(p);
Change the ajax option to dataType: "text", or just omit it
However you can improve your script as noted below
$.ajax({
type: "POST",
url: '#Url.Action("receive", "Main")', // don't hardcode url's
data: { p: $("#txtname").val() }, // no need to stringify (delete the contentType: option)
dataType: "json",
success: function (result) {
alert('Yay! It worked!');
},
error: function (result) {
alert('Oh no zzzz:('+result.responseText);
}
});
or even simpler
$.post('#Url.Action("receive", "Main")', { p: $("#txtname").val() }, function(result) {
alert('Yay! It worked!');
}).fail(function(result) {
alert('Oh no zzzz:('+result.responseText);
});
Notes: You should always use #Url.Action() to generate the correct urls, and it is not necessary in this case to stringify the data (but you need to remove the contentType: line so it used the default application/x-www-form-urlencoded; charset=UTF-8)
In addition, this is not strictly a POST (your not changing data on the server - but I assume this is just for testing). And there is no point in the line ViewBag.name = p; - it does nothing in your context, and as soon as you return from the method, ViewBag is lost anyway.
try to change your controller code as follows
[HttpPost]
public ActionResult List(string p)
{
ViewBag.name = p;
return Json(ViewBag);
}
Your controller method should look like this:
[HttpPost]
public ActionResult receive(string p)
{
return Json(p);
}
I have write down a script as following
var reason = prompt("Please Enter the Reason", "");
if(reason != null)
{
// alert('you are here');
$.ajax({
type: "POST",
url: "/Controller/ActionMethod",
content: "application/json; charset=utf-8",
dataType: "json",
data: Json.stringify(reason),
success: function(){ alert('Data Sent');}
});
}
which works fine as it calls the ActionMethod from the controller but i am not being able to retrieve data taken with the help of prompt. within the controller.
I have tried
String reason = Request["reason"];
as well as i have tried to pass the data as argument in controller
public ActionResult ActionMethod(int id, string reason)
but in all cases reason is null. please tell me how can i retrieve the reason from the same.
thanks in advance
$.ajax({
type: 'POST',
url: "/Controller/ActionMethod",
data:{'reason':reason},
dataType: 'json',
success: function(jsonData) {
},
error: function(error) {
}
});
Your action maybe like this
[HttpPost]
public ActionResult ActionMethod(string reason){
...
return Json(obj);
}
this should work: Request.Form["reason"].
I'm using ASP.NET MVC3 with Jquery. I'm trying to pass my form elements back to the controller using something like this (Please note I removed success and error code for simplicity):
var formElements = $("#myForm").serialize();
$.ajax({
type: "POST",
url: ScriptResolveUrl("~/Report/SubmitChanges"),
data: {collection: formElements},
success:
error:
dataType: "json"
});
My question is what should the parameter in my controller method look like:
Here is my controller method:
public ActionResult SubmitChanges(WHAT GOES HERE?)
{
}
So what I'm really looking for is what should be the type of the parameter going into the controller method? I want to be able to retrieve the values of the form elements in the controller.
So here is what I did. I have about 20-30 elements on my form so I really didn't want to have to turn each one into a parameter or list them all out in the collection.
In the jquery, I did the following:
var formElements = $("#myForm").serialize();
$.ajax({
type: "POST",
url: ScriptResolveUrl("~/Report/SubmitChanges"),
data: { parms: formElements },
success:
error:
dataType: "json"
});
It then goes into my controller as a string:
public ActionResult SubmitChanges(string parms)
I then found a function to parse that string (seems to be working)
NameValueCollection qscoll = HttpUtility.ParseQueryString(parms);
This seems to work without listing out all of the form elements.
Assuming your form elements all correspond to your model (let's say it's MyModel), then it should simply be:
public ActionResult SubmitChanges(MyModel model)
{
}
MVC default model binding will do the rest :).
Make sure you change your data definition in the jQuery ajax method though, you've already serialized it. Just do:
data: formElements,
I'm assuming the following in your jQuery ajax method is a copy and paste error?
success:
error:
If it's not, then make sure you either remove it, or change them to:
success: function (result) {
//do something
},
error: function () {
//do something on error
}
The problem is that their is no model that corresponds to my form
elements.
Then you can have this:
public ActionResult SubmitChanges(int id, string name)
{
}
And then pass in the individual items:
var o = {
id = $("#id_elem_id").val(),
name = $("#name_elem_id").val()
}
$.ajax({
type: "POST",
url: ScriptResolveUrl("~/Report/SubmitChanges"),
data: JSON.stringify(o),
success:
error:
dataType: "json"
});
where id_elem_id and name_elem_id are the ids of your html elements. And add any additional parameters you need, just follow along.
You were almost there. Just get rid of the brackets around your data parameter:
var formElements = $('#myForm').serialize();
$.ajax({
type: 'POST',
url: ScriptResolveUrl("~/Report/SubmitChanges"),
data: formElements,
success: function(result) {
// handle the success of the AJAX request
},
error: function() {
// an error occurred
}
});