Ajax call works but the passed object is empty.
Its a simple setup of passing a cart object to a controller action.
The call happens but man is empty when it hits the Action.
The paylod being sent(in chrome) is:
{"man":"testtext2"}
The response is:
{"man":null}
.net cartitem:
public class Cartitem
{
public string man { get; set; }
}
Javascript cartitem:
class cartitem {
constructor( _man, ) {
this.man = _man;
}
}
Controller Action:
[HttpPost]
public ActionResult AddToCart(Cartitem myCartitem)
{
//ERROR: cartitem values are coming in empty
return Json(myCartitem);
}
Javascript
$(".AddLink").click(function () {
var json = JSON.stringify(c);
var cartitem = JSON.stringify({
'man': 'testtext2',
});
$.ajax({
type: "POST",
url: '#Url.Action("AddToCart", "ShoppingCart")',
contentType: "application/json; charset=utf-8",
dataType: "json",
data: cartitem,
success: function (data) {
alert("Data Back: " + data.man);
}
});
});
Edit
To remove a a lot of red hearings, I've simplified the code so its one single string(man).
The result is the same, MyCartitem is coming in empty.
Add [FromBody] to the Action method e.g
public ActionResult AddToCart([FromBody] Cartitem myCartitem)
{
}
2 days lost!
Related
I have JavaScript function where I have an array and when I send that array to my C# controller, it should be in such way way that my controller should understand.
JavaScript function
function Check(obj) {
var eArray = $('..').map(function () {
return this.getAttribute("value");
}).get();
$.ajax({
url: "/Order/Check",
data: { GUID: JSON.stringify(eArray) },
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
});
My Controller
public ActionResult Check()
{
string guid = HttpContext.Request["GUID"];
var result = //send the result
return Json(result, JsonRequestBehavior.AllowGet);
}
I would like to get an array in my controller.
I'm not really sure what you are trying to achieve. From what I saw in your comments, you are sending an array of GUIDs to your controller, but that results in it being send as a string, and you want an array.
I tested your code and modified it a bit:
$.ajax({
type: "POST",
url: /your url/,
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
data: JSON.stringify({GUID: eArray}),
});
Where eArray is let eArray = ['D5FAF478-CF43-40E1-BE79-BB90147A3194', '2E79B23E-D264-4901-A065-7E0B7032A5D8']
Then, in my controller, I receive it as a model:
public class Dto
{
public string[] GUID { get; set; }
}
Then, you can use it like this:
[HttpPost]
public IActionResult Post([FromBody] Dto dto)
{
var listOfGuids = dto.GUID.Select(guid => Guid.Parse(guid)).ToList();
var result = Services.CheckRecords(listOfGuids);
...
}
It seems that unfortunately the standard JavaScriptSerializer.Deserialize doesn't handle Guid type.
Therefore, I would go with something like
public ActionResult Check()
{
string guidsStr = HttpContext.Request["GUID"];
var guids = new List<Guid>();
foreach (var guid in Regex.Replace(guidsStr, "[\\[\\\"\\]]", "").Split(",")) {
Guid newGuid;
if (Guid.TryParse(guid, out newGuid)) {
guids.Add(newGuid);
} else {
// handle invalid guide value
}
}
// guids list now contains parsed Guid objects
// do here what you need to do with the list of guids
return Json(result, JsonRequestBehavior.AllowGet);
}
Please let me know if this helps.
In my web service (order.asmx) I have a method which accept a viewmodel as a parameter. Method signature is below.
public string CreateOrder(OrderModel order)
and my order.cs is like below,
public class OrderModel: BaseClass
{
public OrderModel()
{
this.RestaurantIDs = new List<long>();
}
public long OrderID { get; set; }
public List<long> RestaurantIDs { get; set; }
}
I'm passing all the order related details using ajax call to this service method. To pass the RestaurantIDs I'm using an array which gives me 500 server error. I tried with stringify as well but didnt work. Anyone can help me with this?
ajax call
function createOrderObject()
{
var order = new object;
order.CustomerName = $("#txtName").val();
order.RestaurantIDs = selectedRestaurants.map(function (obj) {
return obj.RestaurantID;
});
}
// here the selectedRestaurants is object array.
function createOrder()
{
var order = createOrderObject();
var url = '/Service/OrderService.asmx/CreateOrder';
var dataSet = '{orderModel:' + JSON.stringify(order) + '}';
var orderInfo = $.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: url,
data: dataSet,
dataType: "json",
error: function () {
giveNotification({ NotificationCode: 500, Message: "Internal Server Error, Please try again." });
loadingImg(ele, "hide");
});
}
the error message }
My controller:
[HttpPost]
public IActionResult UserRoleChanged(string roleName,string userName)
{
var a = roleName;
var b = userName;
return RedirectToAction("UserManager");
}
Script in view:
if (window.confirm('Are you sure that you want to change role?')) {
jQuery.ajax({
type: "POST",
url: "#Url.Action("UserRoleChanged", "DashBoard")",
dataType: 'json',
data: { 'roleName': this.text, 'userName': 'SomeName'},
cache: false,
success: function (data){
window.location.href = data;
},
failure: function (data) {
}
})};
When I run script above UserRoleChanged action does not invoke. If I try to remove userName variable from data in ajax then UserRoleChanged action method invokes without any problem. How can i pass multiple data to my controller? What is wrong with my code?
Remove the dataType: 'json' from the ajax, and try again. As you are trying to get the values on server side as normal variable, so dataType: 'json' is not required here.
You can create a model with same properties and pass it as a parameter. Its a good practice.
Looks like this.
public class User
{
public string RoleName { get; set; }
public string UserName { get; set; }
}
And the json looks like this example
{
"RoleName" : "somename",
"UserName" : "somename"
}
In my javascript i make a JSON like object with two properties : ControllerName and WordNumber and add them to an Array.
function TestN() {
var list = new Array();
$("*[wordNum]").each(function ()
{
var endRes = {
ControllerName: this.id,
WordNumber: this.getAttribute("wordNum")
};
list.push(endRes);
});
jQuery.ajax({
url:' #Url.Action("Translate")' ,
contentType: "application/json",
dataType: "json",
data: { List : JSON.stringify(list) }
,
traditional: true
})
}
</script>
In .net I've got this class with the same properties :
public class TranslateModel
{
public string ControllerName { get; set; }
public string WordNumber { get; set; }
}
And here is my action+
public ActionResult Translate(ICollection<TranslateModel> List)
{ return View(); }
As you may suppose the List property in Translate Action is empty (model binding doesn't work);
when you used JSON.stringify(list), it send string value to the controller action, instead of the object.
there are two approaches
1) either you send string to controller's action and Deserialize string to object and use.
2) create the model property as array of list and send that model to controller action without using JSON.stringify.
here are two links that may help you.
--approach-1
ASP.NET MVC 4 JSON Binding to the View Model - Nested object error
--approach-2
Passing json list to MVC 3
Try changing your AJAX function to this:
jQuery.ajax({
url: ' #Url.Action("Translate")',
type: 'POST',
contentType: "application/json",
dataType: "json",
data: JSON.stringify({ 'List': list }),
traditional: true
});
I have this jquery ajax get method on an Index razor in my application:
$.ajax({
url: "#Url.Action("SubmitProjectForPreapproval", "api/Project")",
type: "GET",
cache: false,
data: { projectId: "#ViewContext.RouteData.Values["ProjectId"]" }
}).done(function (data) {
var count = 0;
$.each(data, function (index, value) {
$("#ulMessages").append("<li>" + value + "</li>");
count++;
});
// Assume validation errors if more than 1 message
if (count > 1) {
$("#btnSubmit").removeAttr("disabled");
}
}).fail(function () {
$("#ulMessages").append("<li>An error occurred. Please try again later</li>");
$("#btnSubmit").removeAttr("disabled");
}).always(function () {
$("#imgAjaxLoader").hide();
});
This calls a method within the api/project controller that returns a list of strings:
[HttpGet]
public List<string> SubmitProjectForPreapproval(int projectId)
{ ... }
What I want to do is convert this to an ajax post method. I've been struggling to do just that for the better part of the day. My question is, what is everything that needs to change in order for this to happen? e.g. - change attribute of the method to [HttpPost], and how do I send it the route value? (int pojectId)
Edit: If I do this it works for some reason:
public List<string> SubmitProjectForPreapproval(/*int projectId*/)
{
int projectId = 3308;
...
}
Not sure why it doesn't find my method if I have the parameter there.
I'm not sure how the #Url stuff formats with your system - but just changing it to something like:
$.ajax({
url: "#Url.Action("SubmitProjectForPreapproval", "api/Project")",
type: "POST",
cache: false,
data: { projectId: "#ViewContext.RouteData.Values["ProjectId"]" }
}).done(function (data) {
If you're bit:
#Url.Action("SubmitProjectForPreapproval
..actually has any ?xxx values in it, you also need to add them into the data: { ... }
The problem was indeed the way I was sending the data to the controller action. I fixed it by doing the following:
Alter the ajax method (make use of JSON.stringify):
var projectIdObject = {
ProjectId: "#ViewContext.RouteData.Values["ProjectId"]",
}
$.ajax({
url: "#Url.Action("SubmitProjectForPreapproval", "api/Project")",
type: "POST",
cache: false,
data: JSON.stringify(projectIdObject),
contentType: 'application/json',
}).done(function (data) { ... }
Add a class to take this stringified value:
public class ProjectIdObject
{
public string ProjectId { get; set; }
}
Alter the controller action method to receive this new object and extract the value I want:
[HttpPost]
public List<string> SubmitProjectForPreapproval(ProjectIdObject projectIdObject)
{
int projectId = int.Parse(projectIdObject.ProjectId);
...
}