MVC5 controller action not called from JSON AJAX Post - javascript

I am sending data from from a javascript app to a MVC5 controller, however when data is submitted to the Submit controller action, it is never called. I have some very simple mappers which create the following JSON object:
function mapContactDto(vm)
{
var contactDto = {};
contactDto.firstName = vm.firstName();
contactDto.lastName = vm.lastName();
contactDto.companyName = vm.companyName();
contactDto.emailAddress = vm.emailAddress();
contactDto.phonePrimary = vm.phonePrimary();
contactDto.phoneSecondary = vm.phoneSecondary();
contactDto.address1 = vm.address1();
contactDto.address2 = vm.address2();
contactDto.city = vm.city();
contactDto.postalCode = vm.postalCode();
contactDto.country = vm.country();
return contactDto;
}
function mapCartItems(vm)
{
var cartItemsDto = new Array();
$.each(vm.selectedOptions(), function (index, step, array) {
var sku = step.selection().sku;
if (sku !== "0") {
cartItemsDto.push(sku);
}
});
return cartItemsDto;
}
/* if i dump the object that is sent to the server with `console.log(JSON.stringify(item))` I get:
{
"skus": ["1001","8GB","201"],
"contact": {
"firstName":"Jon",
"lastName":"Doe",
"companyName":"Yup my company",
"emailAddress":"contact#me.com",
"phonePrimary":"012111 231",
"phoneSecondary":"",
"address1":"1 Billing Way",
"address2":"Navigation House",
"city":"London",
"postalCode":"112211",
"country":"GB"
}
}
*/
I then send the data with the following code:
var contactDto = mapContactDto(self.billingVm());
var cartItemsDto = mapCartItems(self.configurationVm());
var req = new XMLHttpRequest();
req.open('HEAD', document.location, false);
req.send(null);
var item = {
skus: mapCartItems(cartItemsVm()),
contact: mapContactDto(billingVm())
};
var url = '/Knockout/Submit';
$.ajax({
cache: false,
url: url,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: item,
type: 'POST',
success: function (data, textStatus, jqXHR) {
},
error: function (data, textStatus, jqXHR) {
}
});
My controller code is below:
public JsonResult Submit(string[] Skus, ContactDto Contact)
{
return Json(new { success = true, message = "Some message" });
}
/* and MVC models are: */
public class ContactDto
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string CompanyName { get; set; }
public string EmailAddress { get; set; }
public string PhonePrimary { get; set; }
public string PhoneSecondary { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
}
I have the following questions please:
Submit is never called however, if I comment out the controller parameters so it becomes Submit() then it is called, why is this?
From the above, it seems like the controller framework cannot match up the parameters - any idea what I am doing wrong please?
How to enable debugging on the MVC controller so I can see what's going on?

Four things you must check using ajax calls,
1. If using javascript object you must stringify the object before passing.
2. The Action verb for the action method should be same as the type of your ajax call if POST then the action method should be decorated by action verb [HttpPost].
3. Always use the relative path for url's in ajax as #Url.Action("action", "controller").
4. The input parameters of your action method method should match the json object parameters (exactly i.e. case sensitive).
For debugging you may use firebug addon in your browser so that you can see what is sent over the network or press F12 for debugging tool in that check in network tab.

You will have to make two changes:
Stringify your Json as below:
$.ajax({
cache: false,
url: url,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(item),
type: 'POST',
success: function (data, textStatus, jqXHR) {
},
error: function (data, textStatus, jqXHR) {
}
});
Second, Just Annotate your Method with [HttpPost] as below:
[HttpPost]
public JsonResult Submit(string[] Skus, ContactDto Contact)
{
return Json(new { success = true, message = "Some message" });
}

Related

Error while creating object to be consumed in in asp.net core controller

I'm having error when creating an object in javascript
I'm having this generic error:
Uncaught SyntaxError: Invalid or unexpected token
That's why i can't solve it. it didn't have specific error message.
This is my model
[Serializable, JsonObject]
public class CompleteOrderRequest : BaseMessageRequest<CompleteOrderRequestDto>
{
}
[Serializable]
[JsonObject, Bind("RequestFrom,RequestBy")]
public abstract class BaseMessageRequest<T> : IBaseMessageRequest<T> where T : class, new()
{
protected BaseMessageRequest()
{
Request = new T();
}
[Required, StringLength(255, MinimumLength = 3)]
[BindProperty(SupportsGet = true), BindRequired]
[FromQuery]
public string RequestBy { get; set; }
[BindProperty(SupportsGet = true)]//, BindRequired]
[FromQuery]
public T Request { get; set; }
}
public class CompleteOrderRequestDto
{
public string OrderNo { get; set; }
}
This is my controller
public async Task<IActionResult> PayNow([FromBody] CompleteOrderRequest request)
{
return View();
}
And this is my javascript code.
var CompleteOrderRequest = {};
CompleteOrderRequest.RequestBy = 'test';
$.ajax({
type: 'POST',
url: '/Orders/PayNow/${CompleteOrderRequest}',
success: function (data) {
if (data.success) {
}
}
});
The error is in this line. I'm encountering error before calling the controller.
CompleteOrderRequest.RequestBy = 'test';
So what's wrong with what Am i doing? And I'm receiving this error
Uncaught SyntaxError: Invalid or unexpected token
When creating your object in JavaScript, you can declare the properties inline like this:
var CompleteOrderRequest = {
RequestBy: "test"
};
You'd also need to ensure you provide that object as the data parameter when posting with ajax.
fix the ajax
$.ajax({
type: 'POST',
url: '/Orders/PayNow',
data: { request: CompleteOrderRequest}
success: function (result) {
if (result.success) {
}
}
});
and when you use only one kind of data from ajax , you don't usually need [FromBody]. Try to change the action too
public async Task<IActionResult> PayNow(CompleteOrderRequest request)
Since you use [FromBody] in action,you need to change your contentType to application/json and convert CompleteOrderRequest to json type:
var CompleteOrderRequest = {};
CompleteOrderRequest.RequestBy = 'test';
$.ajax({
type: 'POST',
url: '/Orders/PayNow',
data: JSON.stringify(CompleteOrderRequest),
contentType:"application/json",
success: function (data) {
if (data.success) {
}
}
});

Pass ID list using ajax call to ViewModel with JQuery

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 }

Get json data from ajax,process it,return answer

I have some troubles with transfer json data.
I have some dynamic page. I collect data to json object "Filters".
var Filters = { daterange: $('#daterange').val(), shop: val_shop, pr: val_pr, plan: val_plan, TabsList: TabsList }
$.ajax({
url: "/Reports/Report_2",
type: "POST",
contentType: "application/json",
dataType: "json",
data: JSON.stringify(
Filters
)
});
I try get it with JObject.
public IActionResult Report_2() //main Action
{
return View();
}
[HttpPost]
public async Task<IActionResult> Report_2([FromBody]JObject jsonResult)//catch json object
{
//do something
return View(_context.MyDatabase.Result);//return data from database for table(Razor Page)
}
I get Error 415. =(
If I try don't overload Report_2 Action().
$.ajax({
url: "/Reports/Report_2_Filter",
type: "POST",
contentType: "application/json",
dataType: "json",
data: JSON.stringify(
Filters
)
});
[HttpPost]
public async Task<JObject> Report_2_Filter([FromBody]JObject jsonResult)
{
return jsonResult;
}
I don't know how return result on Report_2 page. I need result on Report_2 Action becouse I must fill table on Report_2 page. I'm newbee in web, so I will be greateful for any help.
May be you need write ("");
var Filters = { "daterange": $('#daterange').val(), "shop": val_shop, "pr": val_pr, "plan": val_plan, "TabsList": TabsList }
You can add a function to be executed on success. Try to add the following to your ajax request:
success: function(data){
// Do something here
}
Have a look here to see the ajax events.
My solution:
I create class which stores variables:
public class FilterModel
{
public string var1{ get; set; }
public string var2{ get; set; }
public string var3{ get; set; }
public string var4{ get; set; }
public List<string> var5{ get; set; }
}
[HttpPost]
public IActionResult Report_2(FilterModel filter)
{
FilterLogic filterLogic = new FilterLogic(_context);
var result = filterLogic.GetResult(filter);
return View();
}
In JS I use jQuery function $.post
$.post("/Reports/Report_2", { var1: $('#var1').val(), var2: var2, var3: var3, var4: var4, var5: var5});

List not binding from JSON in POST

I have written a POST request that accepts my Model but once I get into the request the List is returning null.
I have read multiple solutions online from adding [FormBody] to checking my naming conventions but nothing seems to work correctly.
In my Script I create an Array var UserPermissions = new Array();
I then push to the array multiple objects:
var permission = {
UserId: #Model.UserId,
AppId: #Model.AppId,
PermissionId: this.value
}
UserPermissions.push(permission);
Then I perform my Ajax request:
$.ajax({
url: '#Url.Action("UpdateUserPermissions")',
data: JSON.stringify(UserPermissions),
type: "post",
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
success: function (status) {
swal("User Permissions have been updated.", { icon: "success" });
},
error: function (xhr, ajaxOptions, thrownError) {
swal("Error updating permissions, please contact support.");
}
});
My Controller POST Request Looks like this:
public IActionResult UpdateUserPermissions([FromBody]PermissionPartialModel model)
{
return View();
}
In every case [FromBody]PermissionPartialModel model is returning null when it should be returning a list.
Here is my Model:
public class PermissionPartialModel
{
public int AppId { get; set; }
public int UserId { get; set; }
public List<UserPermissionsModel> UserPermissions { get; set; }
}
What could be causing this and what is a solution to fix this?
var UserPermissions= {
UserId: #Model.UserId,
AppId: #Model.AppId,
PermissionId: this.value
}
//UserPermissions.push(permission);
$.ajax({
url: '#Url.Action("UpdateUserPermissions")',
data: UserPermissions,
type: "post",
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
success: function (status) {
swal("User Permissions have been updated.", { icon: "success" });
},
error: function (xhr, ajaxOptions, thrownError) {
swal("Error updating permissions, please contact support.");
}
});
You are sending an array from view but receive object in controller. You need to change your parameter type from object to list
public IActionResult UpdateUserPermissions([FromBody]List<PermissionPartialModel> model)
{
return View();
}
This will map but you will get UserPermissions null. To solve this you need to make changes in PermissionPartialModel and permission object in view.
permission
var permission = {
UserId: 2,
AppId: 2,
UserPermissions: { PermissionId: 2 }
}
UserPermissions.push(permission);
PermissionPartialModel
public class PermissionPartialModel
{
public int AppId { get; set; }
public int UserId { get; set; }
public UserPermissionsModel UserPermissions { get; set; }
}

MVC [HttpPost] Method receives null parameter

I'm sending a value through JQuery to an MVC HttpPost action method, but instead it is getting a null value. When I send a plain string it works fine, but when I send an array it gets the null value. Here is the code.
code to send the value
function Submit() {
var QSTR = {
name: "Jhon Smith",
Address: "123 main st.",
OtherData: []
};
QSTR.OtherData.push('Value 1');
QSTR.OtherData.push('Value 2');
$.ajax({
type: 'POST',
url: '/Omni/DoRoutine',
data: JSON.stringify({ obj: 'Reynor here!' }),
// this acctually works
// and at the action method I get the object[]
// with object[0] = 'Reynor here!'
// but when I use the object I really need to send I get null
data: JSON.stringify({ obj: QSTR }), //I get null
contentType: 'application/json; charset=utf-8',
dataType: "json",
success: function (msg) {
alert('ok');
},
error: function (xhr, status) {
alert(status);
}
});
}
this is the action method code:
[HttpPost]
public ActionResult DoRoutine(object[] obj)
{
return Json(null);
}
What is the solution for this and why is this happening?
thanks
QSTR is a complex type, so you need complex data in your post method.
public class QSTR
{
public string name { get; set; }
public string Address { get; set; }
public object[] OtherData { get; set; }
}
[HttpPost]
public ActionResult DoRoutine(QSTR obj)
{
return Json(null);
}
But if you want receive only array of otherdata you should send only in in your ajax:
$.ajax({
data: JSON.stringify({ obj: QSTR.OtherData }),
// other properties
});

Categories