Passing a string array from JS to C# controller - javascript

I have an array in JS ( var selectedEmails = []; )
After I collect the selected Emails from a grid, I call a GET to C# controller:
$.ajax({
type: 'GET',
url: '#Url.Action("SendEmailBatchs", "account")',
data: { emails: selectedEmails },
contentType: 'application/json',
success: (data) => {
console.log("data", data);
}
})
When called, the parameter in C# gets no data. I've checked in JS, and the emails are in the array. Using breakpoints, I've confirmed the Controller's method is getting called:
Controller:
[HttpGet("sendemailbatchs")]
public async Task<ActionResult> SendEmailBatchs(string[] emails)
{
...
foreach (ApplicationUser user in users)
{
await SendEmailConfirmation(user);
}
return Ok;
}
Changing the data to data: { emails: JSON.stringify(selectedEmails) }, will pass an array with 1 element only, containing a stringified list of emails "[\"loes.vea#phanc.com\",\"MaAlonso.Mfizer.com\",\"cech#mll-int.cm\",\"jier.aris#si.com\"]"
What would be the correct parameter from JS so that I get a string ARRAY where each email is an element of the array?
emails = [0]: "loes.vea#phanc.com\",
[1]: \"MaAlonso.Mfizer.com\", ...

There is a gap between what you are expecting in the controller and what you are sending through ajax call.
public async Task<ActionResult> SendEmailBatchs(string[] emails)
Let's understand the parameter of the above function, you are expecting an array of strings and will refer to it as emails in the function body. So, you will have to pass an array of strings in the request body.
PFB my simple controller and corresponding ajax call:
[HttpGet("api/test")]
public ActionResult<int> RecieveData(string[] emails)
{
return emails.Count();
}
Call from UI like this:
var settings = {
"url": "https://localhost:5000/api/test",
"method": "GET",
"headers": {
"Content-Type": "application/json"
},
"data": JSON.stringify([
"john#example.com",
"jane#example.com"
]),
};
$.ajax(settings).done(function (response) {
console.log(response);
});

so, after following Devesh's suggestions I ended up with
var settings = {
"url": '#Url.Action("SendEmailBatchs", "account")',
"method": "GET",
"headers": {
"Content-Type": "application/json"
},
"data": {
emails: JSON.stringify(selectedEmails)},
};
the issue persisted, because I needed to DESERIALIZE the result, in C#:
public async Task<ActionResult> SendEmailBatchs(string emails)
{
var selectedEmails = JsonConvert.DeserializeObject<string[]>(emails);
//DO STUFF
}
Thx

Related

Parse return value from $ajax call in JavaScript from MVC Controller

I'm using VS2022 with C# and I'm trying to use an $ajax get method in my JavaScript function. I'm sending a parameter and returning a string[] list but when I receive the return I use JSON.stringify but when I try to use JSON.Parse it fails. The Javascript code is
$.ajax({
type: "GET",
url: '/Home/GetCategories/',
contentType: 'application/json',
datatype: 'json',
data: { ctgData: JSON.stringify(relvalue)}
}).done(function(result) {
let userObj = JSON.stringify(result);
let resultList = JSON.parse(userObj);
});
The code in the controller which returns the list is simple at the moment until I get the return working
[HttpGet]
public ActionResult GetCategories(string ctgData)
{
string[] categoryList = { "Food & Drink", "Sport & Fitness", "Education", "Housework", "Fiction", "Horror Books", "Fantasy", "Magic" };
return Json(new { data = categoryList });
}
The value in result is
{"data":["Food & Drink","Sport & Fitness","Education","Housework","Fiction","Horror Books","Fantasy","Magic"]}
I've tried a number of different ways in Parse but it always fails, can you tell me what I'm missing to get my resultList to contain the string array.
You don' t need to parse anything. It is already java script object
$.ajax({
type: "GET",
url: '/Home/GetCategories/',
contentType: 'application/json',
datatype: 'json',
data: { ctgData: JSON.stringify(relvalue)}
sucess: function(result) {
let data=result.data; // data = ["Food & Drink","Sport & Fitness",..]
}
});
use this:
JSON.parse(JSON.stringify(data))
const data = {"data":["Food & Drink","Sport & Fitness","Education","Housework","Fiction","Horror Books","Fantasy","Magic"]}
const resultJSON = JSON.parse(JSON.stringify(data))
console.log("json >>>", resultJSON)

Ajax POST an object with javascript, but the value in backend is null, why?

So on button click there is a function sendEmail(). Alert is working fine, I can see my datas there. But on backend I can't see anything, just everything is null.
function sendEmail() {
var datas = new Object();
datas.mail = $('#contactDropdownList').val();
datas.mailobject = $('#emailObject').val();
datas.text = $('#emailText').val();enter code here
alert(datas.mail + datas.mailobject + datas.text);
$.ajax({
type: "POST",
dataType: "json",
url: "/Email/sendEmail",
contentType: 'application/json; charset=UTF-8',
data: JSON.stringify({ items: datas }),
success: function (data) {
console.log(data);
//do something with data
},
error: function (jqXHR, textStatus, error) {
//log or alert the error
console.log(error);
}
});
}
C# code:
public class MyClass
{
public string Email { get; set; }
public string Object { get; set; }
public string Text { get; set; }
}
[HttpPost]
public IActionResult sendEmail(MyClass items)
{
return Json(new { data="Ok" });
}
items.Email, items.Object and items.Text are null.
And the return valu is null as well, because in javascript success: function (data) { console.log(data);
is empty string.
What can be the problem? Thank you!
Model binder expects json content to match C# class. Your datas object should look like that
var datas = {
email: $('#contactDropdownList').val(),
object: $('#emailObject').val(),
text: $('#emailText').val()
}
Since you wrapped your object ({ items: datas }), you may think it will be mapped to sendEmail(MyClass items), but in reality items name does not matter, you can change variable name to any other name you like
Make sure you apply [FromBody] attribute to your parameter like that
[HttpPost]
public IActionResult sendEmail([FromBody]MyClass items)
Complete demo:
<script>
function sendSmth() {
var data = {
Email: 'email',
Object: 'object',
Text: 'text'
};
$.ajax({
type: "POST",
dataType: "json",
url: "/home/index",
contentType: "application/json",
data: JSON.stringify(data),
success: function (datas) {
console.log(datas)
}
})
}
</script>
And controller
[HttpPost]
public IActionResult Index([FromBody]MyClass obj)
{
return View();
}
As someone has noted, you have a mismatch between what you're sending to the controller and what the model the modelbinder is expecting. You can also vastly simply your AJAX code:
function sendEmail() {
var data = {
Email: $('#contactDropdownList').val(),
Object: $('#emailObject').val(),
Text: $('#emailText').val()
};
$.post("/Email/sendEmail", data)
.done(function (response) {
console.log(response);
//do something with response
})
.fail(function (jqXHR, textStatus, error) {
//log or alert the error
console.log(error);
});
}
You don't really need to specify the content type or data type - the $.post helper's defaults work just fine for what you've shown.

Ajax POST int to MVC

I'm trying to POST an INT with Ajax to my MVC controller.
The script debugging confirms that my variable is an INT with a value (for example 8 and not a string "8"). All lines of code are executed and
I recive my Alert error message.
I've got a breakpoint inside of my Action in the controller but I never get that far. I get a notice in my Action that a request failed, but it only say
"POST Order/Delete". My Controller name is OrderController and Action name is Delete.
My JavaScript:
//Delete order
$(".deleteOrder").on("click", function () {
var id = parseInt($(this).attr("id"));
if (id !== null) {
$.ajax({
url: "/Order/Delete",
method: "POST",
contentType: "application/JSON;odata=verbose",
data: id ,
success: function (result) {
alert("Ok")
},
error: function (error) {
alert("Fail");
}
});
}
});
My MVC Action
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id)
{
List<OrderRow> lstOrderRow = new List<OrderRow>();
lstOrderRow = db.OrderRows.Where(x => x.OrderId == id).ToList();
foreach(var row in lstOrderRow)
{
db.OrderRows.Remove(row);
}
Order order = new Order();
order = db.Orders.Find(id);
db.Orders.Remove(order);
db.SaveChanges();
return RedirectToAction("index");
}
You should either use the url like this by removing data field
url: "/Order/Delete/" + id,
or send the id in data as below
data: {id: id},
This works for me:data: JSON.stringify({ id: id})
dataType: "json",
contentType: 'application/json; charset=utf-8',

Insert variable value into ajax post data

I have created a form with textboxes and a dropdown menu, inside my code I've created a script which will be called when clicking "Send Form"
Lets say my field are : firstName, lastName, country (dropdown)
Here is the script:
function f1() {
var settings = {
"async": true,
"url": "https://api.TheSite.com/v2/applications/123456789/newJson.json",
"method": "POST",
"headers": {
"x-api-key": "123456789123456",
"content-type": "application/json",
},
"processData": false,
"data": "{\r\n \"deployment\": {\r\n \"revision\": \"string\",\r\n \"changelog\": \"string\",\r\n \"description\": \"string\",\r\n \"user\": \"string\"\r\n }\r\n}"
}
$.ajax(settings).done(function(response) {
console.log(response);
alert("The Form Was Sent");
});
}
I would like to insert those 3 variables' values inside the "data" string like so:
"data": "{\r\n \"deployment\": {\r\n \"revision\": \`firstName
\",\r\n \"changelog\": \"`lastName
and so on...
In the dropdown menu, I assume it will be displayed as an array. How do I include my variable inside?
First create an empty object and insert the data into it.
Next use JSON.strigify() to convert that into a JSON blob before you send it over to the server.
var data = {};
data.deployment = {};
data.deployment.revision = firstName;
data.deployment.changelog = lastName;
var settings = {
....,
data: JSON.stringify(data)
};
Since you are already using jQuery to perform your AJAX request, you should be aware that you can actually pass a native JavaScript object into the data portion of the request. You don't need to have it converted to a JSON string. If you want to, you can just stringify it.
You can actually establish default request options and then merge them with the data you want to request.
var defaults = {
url: 'https://api.TheSite.com/v2/applications/123456789/newJson.json',
method: 'POST',
contentType: 'application/json',
headers: {
'x-api-key': '123456789123456',
},
processData: false,
async: true
};
function makeXhrRequest(config) {
var xhrRequest = $.extend(true, defaults, config);
// If you want to convert the request to a json String.
//xhrRequest.data = JSON.stringify(data);
$.ajax(xhrRequest).done(function(data, textStatus, jqXHR) {
console.log(data);
alert("The Form was sent...");
});
}
var $myForm = $('form[name="my-form"]');
makeXhrRequest({
data : {
deployment : {
revision : $myForm.find('input[name="firstname"]').val(),
changelog : $myForm.find('input[name="lastname"]').val(),
description : 'string',
user : 'string'
}
}
});
SOLVED
this is the syntax that worked for me +$("#firstName")[0].value+ and this is the code :
"data":"{\r\n\deployment\: {\r\n revision\:"+"\""+$("#firstName")[0].value+"\","+"\r\n"

Passing an array of Javascript classes to a MVC controller?

I am trying to pass an array of services to my controller.
I've tried a bunch of different ways to get it work, serializing the data before going to controller, serializing each service, only thing that seems to work is changing the controller parameter to string and serializing array, then using JsonConvert, but I'd rather not do that.
With the specified code, I am getting the correct number of items in the List, but they all contain a service id with an empty guild, and service provider id is null.
Any ideas?
Javascript
function ServiceItem() {
this.ServiceProviderID = 'all';
this.ServiceID = '';
}
var selecteditems= (function () {
var services = new Array();
return {
all: function() {
return services;
},
add: function(service) {
services.push(service);
}
};
})();
var reserved = [];
$.each(selecteditems.all(), function(index, item){
reserved.push({ ServiceID: item.ServiceID, ServiceProviderID: item.ServiceProviderID});
});
getData('Controller/GetMethod', { items: reserved }, function(result) {
});
var getData = function (actionurl, da, done) {
$.ajax({
type: "GET",
url: actionurl,
data: da,
dataType: "json",
async: true,
success: function (d) {
if (typeof (done) == 'function') {
var str = JSON.stringify(d);
done(JSON.parse(str));
}
}
});
};
Controller
public JsonResult GetMethod(List<CustomObject> items)
{
}
Custom Object
public class CustomObject
{
public Guid ServiceID {get;set;}
public Guid? ServiceProviderID {get;set;}
}
Set the content-type and use POST instead of GET (as it is a list of complex type objects). mark your action with HttpPost attribute too.
See if this works:-
$.ajax({
type: "POST",
url: actionurl,
data: JSON.stringify(da),
dataType: "json",
contentType: 'application/json',
async: true,
success: function (d) {
if (typeof (done) == 'function') {
var str = JSON.stringify(d);
done(JSON.parse(str));
}
}
});

Categories

Resources