Get data from ajax to mvc action - javascript

I want to send array of objects from ajax call to controller action.
On back-end side I have
container classes:
public class MyContainer
{
public string Id { get; set; }
public Filter[] Filters { get; set; }
}
public class Filter
{
public string Name { get; set; }
public string[] Values { get; set; }
}
and action:
public ActionResult MyAction(MyContainer container)
{
var id = container.Id;
foreach(Filter filter in container.Filters)
{
//Do something
}
}
On front-end side I have
$(document).on('click', 'mySelector', function (event) {
//Create first object
var firstIds = {};
firstIds.Name = "Custom Name 1";
firstIds.Values = GetIds('param1'); //this return an array of strings
//Create second object
var secondIds = {};
secondIds.Name = "Custome Name 2";
secondIds.Values = GetIds('param2'); //another array
var Id = $(this).attr('id'); //id of element
//Add objects to array
var filters = [];
filters.push(firstIds);
filters.push(secondIds);
$.ajax({
method: "GET",
url: baseUrl+"/MyAction",
//traditional: true, //I tried with and without that parameter
data:
{
Id: Id,
Filters: filters
},
contentType: 'application/json',
success: function (res) {
alert('success')
}
});
});
So if I use it like in example on top, container-object in action have Id value and have array of 2 elements in Filters, however both of them have Name and Values as null.
With traditional set to True, I got container.Id set but container.Filters = null.
Any suggestion?
Thank you.

Use a POST request in combination with JSON.stringify() method.
C#
[HttpPost]
public ActionResult MyAction(MyContainer container)
{
var id = container.Id;
foreach(Filter filter in container.Filters)
{
//Do something
}
}
JQUERY
$.ajax({
method: "POST",
url: baseUrl+"/MyAction",
data:JSON.stringify(
{
Id: Id,
Filters: filters
}),
contentType: 'application/json',
success: function (res) {
alert('success')
}
});
Why do you need JSON.stringify() method ?
contentType is the type of data you're sending, so application/json; The default is application/x-www-form-urlencoded; charset=UTF-8.
If you use application/json, you have to use JSON.stringify() in order to send JSON object.
JSON.stringify() turns a javascript object to json text and stores it in a string.

You should use POST method instead of GET in ajax request. As you are posting data. and also your action should have [HttpPost] decorator.
$.ajax({
method: "POST",
url: baseUrl+"/MyAction",
data:
{
Id: Id,
Filters: filters
},
contentType: 'application/json',
success: function (res) {
alert('success')
}
});

Though its an old post, adding my bit to it. I would ask if you are returning a view from the action or not? here it seems like you are not returning a view but just wanting to update some data.
But in case you wanted to return a view, for e.g like showing some product info, then you would just pass the selected product's id to the action method, retrieve the related product information and then pass on this data as a model to the view, and then return the complete view. In this case you don't need a separate ajax call to process the data, instead just do it when you are requesting for the view itself (through the action method).
On the contrary if you already have the view rendered and are just wanting to change the data inside the current view then just resort to an ajax call to get the data without any view.
Hope it helps

Related

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 }

Model vs List<Model> when sending post request to controller using Ajax

I have been trying to send a list model to controller using ajax but it seems it is not working at all
Model
public string MyModel {
public string myfieldName {get;set;}
}
controller
public JsonResult Create(List<myModel> list)
{
return Json("Success");
}
post request
$("body").on("click", "#btnSave", function () {
var list= new Array();
list = [{ myfieldName: 'ABC' }, { myfieldName: 'DEF' }];
//Send the JSON array to Controller using AJAX.
$.ajax({
type: "POST",
url: "/Project/Create",
data: JSON.stringify({ list }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
alert(r + " record(s) inserted.");
}
});
});
so when I send this through, I check the browser and I can see that the request payload is sent with json object list
However when I go to controller the list is not binding it at all, so I check the http.context to check the request payload there and it all empty.
on the other hand when I change the controller like below
sending request with only model
public JsonResult Create(myModel data)
{
return Json("Success");
}
and change the js with below
$("body").on("click", "#btnSave", function () {
var data ={};
data.myfieldName= "test";
//Send the JSON array to Controller using AJAX.
$.ajax({
type: "POST",
url: "/Project/Create",
data: data,
success: function (r) {
alert(r + " record(s) inserted.");
}
});
});
the only difference here is that I don't send as json, so my question what is the is the difference between sending model vs a list of model using ajax
and what can I change to get the controller to bind the data or accept a list of model data
noting i'm using .Net core 2.0
Thank you
I usually use this method to send my Model as a List to my Controller method. I will try to show you regarding your scenario, how you can do this:
AJAX:
$("body").on("click", "#btnSave", function () {
var list= new Array();
list = [{ myfieldName: 'ABC'}, { myfieldName: 'DEF'}];
//Send the JSON array to Controller using AJAX.
$.ajax({
type: "POST",
url: "#Url.Action("Create","Project")",
data:{"json": JSON.stringify(list)},
dataType: "json",
success: function (r) {
alert(r + " record(s) inserted.");
}
});
});
And you can receive your Model like this in your Create method:
Make sure to import the System.Web.Script.Serialization namespace:
using System.Web.Script.Serialization
[HttpPost]
public JsonResult Create(string json)
{
var serializer = new JavaScriptSerializer();
dynamic jsondata = serializer.Deserialize(json, typeof(object));
List<string> myfieldName=new List<string>();
//Access your array now
foreach (var item in jsondata)
{
myfieldName.Add(item["myfieldName"]);
}
//Do something with the list here
return Json("Success");
}
Hope this helps you out.
Another method would be to utilize unobtrusive AJAX. All you would need is to install Microsoft jQuery unobtrusive AJAX from your Nuget Package Manager.
Then, in your view, call the following:
#{using (Ajax.BeginForm("Create", "ControllerName", null, new AjaxOptions()
{
HttpMethod = "POST",
// ...
}
}))
{
// Html code goes here
}
And also make sure that you include this at the bottom of your view:
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
Then, you can have a normal ActionResult setup (instead of JsonResult) for your controller and accept an argument of List list.

Map list of objects from client to server

I would like to map a list of objects from client to server, using MVC. On the server I see that list is populated with correct number of items, but properties are empty. What am I doing wrong?
Here is the code from client:
var listCAORAS = [];
$('span.chkDelete input[type=checkbox]:checked').each(function (i, obj) {
var iORAS_KEY = $(obj).parent().attr('data-ioras_key');
if (iORAS_KEY) {
listCAORAS.push({ "iORAS_KEY": Number(iORAS_KEY) });
}
});
$.ajax({
method: 'post',
url: '/OrderSupplier/DeleteCAORAS/',
data: {
listCAORAS: listCAORAS
}
});
Server side:
public JsonResult DeleteCAORAS(List<DTO_CAORAS> listCAORAS)
{
}
public class DTO_CAORAS
{
public int? iORAS_KEY { get; set; }
//many more properties here
}
The default jQuery ajax contentType is 'application/x-www-form-urlencoded; charset=UTF-8' which means in order to bind to you model, the format of your data would need to be
$.ajax({
....
data: { [0].iORAS_KEY: 1, [1].iORAS_KEY: 1, [2].iORAS_KEY: 1, ... }
});
i.e your object names need to have zero-based, consecutive collection indexers.
Note that if your view is correctly generated (i.e. your checkboxes are bound to a bool property and you have a hidden input for the iORAS_KEY property), then all you would need is
$.ajax({
....
data $(yourForm).serialize()
});
To send an array of complex objects as you are doing, you must set the contentType to 'json' and stringify the data which instructs the DefaultModelBinder to use the JsonValueProviderFactory to deserialize the data to your model.
$.ajax({
url: '#Url.Action("DeleteCAORAS", "OrderSupplier")', // always use Url.Action() to generate the url
....
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ listCAORAS: listCAORAS })
});

Why ASP MVC model binder only accept JSON in POST?

Whenever I send 'GET' with JSON.stringify() using AJAX, model value is always accept null;
Why it can only bind 'POST'?
If it is possible, can I use 'GET' and still bind data to model?
Edit: adding Code Example
JS:
$.ajax({
var modelsend = {
itemname: 'shoe',
itemcolor: 'red',
itemsize: '31',
itemvariety: 'SR-31',
}
type: "POST",
url: "#Url.Action("ShowData", "Controller")",
data: JSON.stringify(modelsend),
dataType: "json",
contentType: "application/json",
success: function (data) {
//do something with data
},
error: function (jqXHR, textStatus, errorThrown) {
//show error
}
});
Model:
public class shoemodel
{
public string itemname { get; set; }
public string itemcolor { get; set; }
public string itemsize { get; set; }
public string itemvariety { get; set; }
}
Controller:
public ActionResult ShowData(shoemodel get)
{
List<DataGrid> fetch = func.getdata(get);
return Json(fetch);
}
Perhaps you are forgetting that GET is used for viewing something, without changing it, while POST is used for changing something. And Get can be used to change something only when you use Querystring. Post on the other hand sends form data directly.
HTTP 'GET' method doesn't support a body in the request. The way to send parameters via 'GET' is using the application/x-www-form-urlencoded format appending them in the URL like this.
http://example.com/?key1=value1&key2=value2

Sending a LIST of JSON object from javascript to MVC action

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
});

Categories