Ajax post parameter always NULL in MVC controller [duplicate] - javascript

I've got an ajax post being constructed like this:
var myData = [
{
id: "a",
name: "Name 1"
},
{
id: "b",
name: "Name 2"
}
];
$.ajax({
type: 'POST',
url: '/myurl/myAction',
data: { items: myData },
dataType: 'json',
error: function (err) {
alert("error - " + err);
}
});
And an MVC controller:
[HttpPost]
public JsonResult MyAction(MyClass[] items)
{
}
MyClass is just a simple representation of the data:
public class MyClass {
public string Name {get; set; }
public string Id {get; set; }
}
When the javascript makes the post request, the controller action does indeed receive 2 items, however the properties (id, name) in these items are null.
Checking the request in fiddler, the body looks like this:
Name | Value
items[0][Name] | Name 1
items[0][Id] | a
items[1][Name] | Name 2
items[1][Id] | b
Have I missed something?

Have I missed something?
Yes, take a look at the following article to understand the correct wire format that the default model binder expects for binding collections. In other words, for this to work, instead of:
items[0][Name] | Name 1
items[0][Id] | a
items[1][Name] | Name 2
items[1][Id] | b
your payload should have looked like this:
items[0].Name | Name 1
items[0].Id | a
items[1].Name | Name 2
items[1].Id | b
Unfortunately with jQuery it can be quite frustrating to achieve this payload. For this reason I would recommend that you use a JSON payload if you want to send complex objects/arrays to your server with AJAX:
$.ajax({
type: 'POST',
url: '/myurl/myAction',
data: JSON.stringify({ items: myData }),
contentType: 'application/json',
error: function (err) {
alert("error - " + err);
}
});
Things to notice:
data: JSON.stringify({ items: myData }) instead of data: { items: myData }
Added contentType: 'application/json'
Gotten rid of dataType: 'json'
Now your payload looks like this:
{"items":[{"id":"a","name":"Name 1"},{"id":"b","name":"Name 2"}]}

you can use this code to solve the problem :
$.ajax({
url: '/myurl/myAction',
data: { '': items },
method: "POST",
dataType: 'json',
success: function (xhr, status, response) {
},
error: function (xhr, status, response) {
}
});
[HttpPost]
public JsonResult MyAction(IEnumerable<MyClass> items)
{
}

Related

Return parameter null in controller from ajax

I don't know what happened the value sent to the controller is always null, even though in the console.log the value is there, please I need help
this is my ajax:
$('#ddlItemName').change(function () {
var ItemCode = $('#ddlItemName').text();
if (ItemCode != '') {
var RequestParam = {
search: ItemCode
}
console.log(RequestParam);
$.ajax({
url: '/Order/CustomerItemOrders',
type: 'POST',
data: JSON.stringify(RequestParam),
contentType: 'application/json; charset=utf-8',
success: function (data) {
alert(data[0].Name);
},
error: function (data) {
toastr.error(data);
}
});
}
$('#ddlItemName').text('');
});
This is my controller :
[HttpPost]
public JsonResult CustomerItemOrders([FromBody] string search)
{
var result = _order.BindCustomerOrders(search);
return Json(result.data);
}
This is my error :
enter image description here
I've tried adding '[FromBody]' but the value parameter still doesn't get sent
I recomend you add the parameter to query
If you insist on pass the value with request body
Try creat a model:
public class SomeModel
{
public string search{get;set;}
}
in your controller:
public JsonResult CustomerItemOrders([FromBody] SomeModel somemodel)
{
.......
}

How to send a list of objects to controller via Ajax using asp net core 3.1?

I am trying to send a list of objects to controller using ajax and asp .net core. My issue is very very simple and there are lots of answers in SO about my issue but none of them solved my issue. I am new at ASP.NET CORE but very experienced at ASP.NET( the normal one).
When debbuging I get a null list of object.
This is my code:
var detalleVenta = new Array();
detalleVenta.length = 0;
$.each($("#tableventa tbody tr"), function () {
detalleVenta.push({
ProductoId: $(this).find('td:eq(6)').html(),
});
});
console.log(detalleVenta);
var datos =
{
// ignore this, i am trying to capture other data.
"Nit": document.getElementById('Nit').value,
"Nombres":document.getElementById('nombres').value,
"NoComprobante":document.getElementById('nocomprobante').value,
"ClienteId":document.getElementById('clienteselect').value,
"Direccion":document.getElementById('direccion').value,
"FormaPago":document.getElementById('selectformapago').value,
// This is the list I want to send to controller
"detalle": detalleVenta,
};
$.ajax(
{
url: '/Venta/GuardarVenta/',
method:"POST",
data: datos,
traditional: true,
success: function(data, state) {
location.reload();
return;
},
error: function(xhr, textStatus, txt) {
alert(xhr.responseText);
return;
}
});
In the console.log(detalleVenta); code I get this:
but when hitting parameters controller, I get this:
Here are my C# code:
public class VentaController : Controller
{
[HttpPost]
public JsonResult GuardarVenta(List<Binderr> detalle, Venta venta)
{
}
}
public class Binderr
{
public string ProductoId {get;set;}
}
The parameter Venta venta captures good the parameters but the list detalle does not. What am I doing wrong?
EDIT: tried public JsonResult GuardarVenta(Binderr[] detalle, Venta venta got same results, list is null in the controller.
Usually the easiest way is to pass the array to the backend in the form of Json.
Here is a simple example:
var detalleVenta =
[
{ id: "1" },
{ id: "2" },
{ id: "3" }
]
$.ajax({
"type": "POST",
"url": '/Venta/GuardarVenta/',
"dataType": "json",
"contentType": "application/json",
"data": JSON.stringify(detalleVenta),
})
Controller(Add [FromBody]):
[HttpPost]
public JsonResult GuardarVenta([FromBody]List<Binderr> detalle)
{
}
Result:

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.

Sending Array Object Data in Javascript to ASP.NET Core Controller using AJAX ()

I've tried all other solutions pertaining to the problem, but still can't find what i'm missing for my code. Here's my AJAX() Code.
var group = JSON.stringify({ 'listofusers': listofusers });
console.log("listofusers : " + JSON.stringify({ 'listofusers': group }));
(Assuming I have my listofusers object ready, and yes i've checked the console and it has data inside.)
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: "POST",
url: url,
data: group,
success: function (data) {
console.log("output : " + JSON.stringify(data));
//doSend(JSON.stringify(data));
//writeToScreen(JSON.stringify(data));
},
error: function (data) {
console.log("error : " + JSON.stringify(data));
},
});
Here's my Server Side Controller.
[HttpPost]
public IActionResult GetMesssage(List<UserModel> listofusers)
{
var g = listofusers;
}
Just a simple fetch from the controller, so I could verify that the data from client side has really been sent.
I've tried the [FromBody] attribute, but still no luck in fetching the data from the server-side.
Here is a working demo like below:
1.Model:
public class UserModel
{
public int Id { get; set; }
public string Name { get; set; }
}
2.View(remove Content-type):
<script>
var listofusers = [
{ id: 1, name: 'aaa' },
{ id: 2, name: 'bbb' },
{ id: 3, name: 'ccc' }
];
var group = { 'listofusers': listofusers };
console.log(group);
$.ajax({
dataType: 'json',
type: "POST",
url: "/home/GetMesssage",
data: group,
success: function (data) {
console.log("output : " + JSON.stringify(data));
},
error: function (data) {
console.log("error : " + JSON.stringify(data));
},
});
</script>
3.Console.log(group):
4.Result:
Update:
Another way by using json:
1.View(change group from JSON.stringify({ 'listofusers': listofusers });
to JSON.stringify(listofusers);):
<script>
var listofusers = [
{ id: 1, name: 'aaa' },
{ id: 2, name: 'bbb' },
{ id: 3, name: 'ccc' }
];
var group = JSON.stringify(listofusers);
console.log(group);
$.ajax({
contentType:"application/json",
dataType: 'json',
type: "POST",
url: "/home/GetMesssage",
data: group,
success: function (data) {
console.log("output : " + JSON.stringify(data));
},
error: function (data) {
console.log("error : " + JSON.stringify(data));
},
});
</script>
2.Controller(add FromBody):
[HttpPost]
public IActionResult GetMesssage([FromBody]List<UserModel> listofusers)
{
//...
}
You can try this one.
First stringify the parameter that you want to pass:
$.ajax({
url: url,
type: "POST",
data: {
listofusers: JSON.stringify(listofusers),
},
success: function (data) {
},
error: function (error) {
}
});
Then in your controller:
[HttpPost]
public IActionResult GetMesssage(string listofusers)
{
var jsonModel = new JavaScriptSerializer().Deserialize<object>(listofusers); //replace this with your deserialization code
}
What we're doing here is passing your object as a string then deserializing it after receiving on the controller side.
Hope this helps.
I found the solution to my problem guys, but I just want a clarification that maybe there's a work around or another solution for this one.
I've studied the data passed by "JSON.stringify();" from AJAX() and it's somehow like this.
"[[{\"ID\":0,\"UserID\":1014,\"Level\":\"support\",\"Department\":\"\",\"Facility\":\"Talisay District Hospital\",\"Firstname\":\"Joseph\",\"Middlename\":\"John\",\"Lastname\":\"Jude\",\"LoginStatus\":false,\"IPAddress\":\"192.168.110.47:12347\"},{\"ID\":0,\"UserID\":1014,\"Level\":\"support\",\"Department\":\"\",\"Facility\":\"Talisay District Hospital\",\"Firstname\":\"Joseph\",\"Middlename\":\"John\",\"Lastname\":\"Jude\",\"LoginStatus\":false,\"IPAddress\":\"192.168.110.47:15870\"}]]"
to which I was wondering that if the JSON format is a factor in parsing the data from the controller side. (Which of course is stupid since there's only one JSON format. (or maybe there's another, if there is, can you please post some source for reference.))
so I tried Serializing a Dummy Data in my model in "JsonConvert.Serialize()" Method and the output JSON data is like this.
[{"ID":0,"UserID":1014,"Level":"support","Department":"","Facility":"Talisay District Hospital","Firstname":"Joseph","Middlename":"John","Lastname":"Jude","LoginStatus":false,"IPAddress":"192.168.110.47:12347"},{"ID":0,"UserID":1014,"Level":"support","Department":"","Facility":"Talisay District Hospital","Firstname":"Joseph","Middlename":"John","Lastname":"Jude","LoginStatus":false,"IPAddress":"192.168.110.47:16709"}]
and I tried sending the output JSON Data from JsonConvert.Serialize() Method to controller via AJAX() and it worked! And I feel so relieved right now as this problem was so frustrating already.
If there's something wrong with what I found, please respond with what might be wrong or correct. Thank you!

AngularJS $http get to ASP.NET Web Api with object in parameters

I'm trying to get filtered data from server using a filtering object I pass to the server side. I have managed to get this working with a post:
angular:
var filter: { includeDeleted: true, foo: bar };
$http({ method: 'post', url: 'api/stuff', data: filter });
web api:
public IEnumerable<StuffResponse> Post([FromBody]Filter filter)
{
return GetData(filter);
}
But i don't want to use a post for this, I want to use a get. But this does not work:
angular
$http({ method: 'get', url: 'api/stuff', params: filter });
web api
public IEnumerable<StuffResponse> Get([FromUri]Filter filter)
{
return GetData(filter);
}
Also tried specifying params: { filter: filter }.
If i try [FromBody] or nothing, filter is null. With the FromUri i get an object at least - but with no data. Any ideas how to solve this, without creating input parameters for all filter properties?
Yes you can send data with Get method by sending them with params option
var data ={
property1:value1,
property2:value2,
property3:value3
};
$http({ method: 'GET', url: 'api/controller/method', params: data });
and you will receive this by using [FromUri] in your api controller method
public IEnumerable<StuffResponse> Get([FromUri]Filter filter)
{
return GetData(filter);
}
and the request url will be like this
http://localhost/api/controller/method?property1=value1&property2=value2&property3=value3
Solved it this way:
Angular:
$http({
url: '/myApiUrl',
method: 'GET',
params: { param1: angular.toJson(myComplexObject, false) }
})
C#:
[HttpGet]
public string Get(string param1)
{
Type1 obj = new JavaScriptSerializer().Deserialize<Type1>(param1);
...
}
A HTTP GET request can't contain data to be posted to the server. What you want is to a a query string to the request. Fortunately angular.http provides an option for it params.
See : http://docs.angularjs.org/api/ng/service/$http#get
you can send object with Get or Post method .
Script
//1.
var order = {
CustomerName: 'MS' };
//2.
var itemDetails = [
{ ItemName: 'Desktop', Quantity: 10, UnitPrice: 45000 },
{ ItemName: 'Laptop', Quantity: 30, UnitPrice: 80000 },
{ ItemName: 'Router', Quantity: 50, UnitPrice: 5000 }
];
//3.
$.ajax({
url: 'http://localhost:32261/api/HotelBooking/List',
type: 'POST',
data: {order: order,itemDetails: itemDetails},
ContentType: 'application/json;utf-8',
datatype: 'json'
}).done(function (resp) {
alert("Successful " + resp);
}).error(function (err) {
alert("Error " + err.status);});
API Code
[Route("api/HotelBooking/List")]
[HttpPost]
public IHttpActionResult PostList(JObject objData)
{ List<ItemDetails > lstItemDetails = new List<ItemDetails >();
dynamic jsonData = objData;
JObject orderJson = jsonData.itemDetails;
return Ok();}

Categories

Resources