Posting object AJAX to MVC controller results in all properties being null - asp.net-mvc

I am trying to post an object from jquery to MVC controller. The object is passed successfully but all the properties are null (or false for bools).
fwiw, if I JSON.stringify myObect then it does not pass at all, theObect in the controller is null.
I am using MVC4, .net 4.5, jQuery 1.9.1
Any help appreciate.
jQuery function
var myObject =
{
Property1: true,
Proerty2: true
};
$.ajax({
type: 'POST',
url: '/myController/StartProcess/',
data: { theObject: myObject }
});
Controller
private async void StartProcess(myObject theObject)
{
// theObect can be seen successfully but property1 and property2 are false
// if I change them to strings they are null
...
}
Class
public class myObject
{
public bool Property1 { get; set; }
public bool Property2 { get; set; }
}
EDIT:
The solution was:
$.ajax({
type: 'POST',
url: '/myController/StartProcess/',
data: myObject
});
If anyone can shed some light as to why this works and nothing else does it would be greatly appreciated. It is not a great solution because I have to put all my parameters in myObject, I cannot pass any additional parameters using this technique. also curious as to why all the info I find online, including official tutorials, say to use data: JSON.Strinify(myObect) but for me this causes all the properties of myObject to be null (or false).
Thanks to Roar all the same, at least I can move past this.

Get this JSON library and stringify() the object like this:
$.ajax({
type: 'POST',
url: '/myController/StartProcess/',
data: JSON.stringify(myObject)
});

try this
$.ajax({
type: 'POST',
url: '/myController/StartProcess/',
data: myObject
});

If you tried to POST your object to an API controller, it would probably work. I had some trouble with this myself. If you're using jQuery, you need to specify that you're sending JSON so the MVC controller will correctly interpret the data.
You could try this:
$.ajax({
contentType: 'application/json',
data: { theObject: myObject },
dataType: 'json',
type: 'POST',
url: '/myController/StartProcess/'
});

Here's what can also make all properties null :
public ActionResult GetPaymentView(CardModel Card)
{
}
If the view is a collection of a model, when you pass a serialized form of one element in the collection to ajax call, the controller expects the same name instance as the class name. I assume that this is the same way without collection but never tried. In this code example we serialize one element of the collection
$.ajax({
url: '/Shipments/GetPaymentView',
type: 'POST',
data: $('#' + ID).serialize(),
success: { onSuccess(); },
error: { onError(jqXHR, textStatus, errorThrown); }
});
The reason why this happens is because the view model is a collection of the CardModel and the serialization is adding CardModel before each properties like this : CardModel.ID=foo&CardModel.bar The model binder takes it as granted and tries to match the instance sent with the property of the controller which it can't and instantiate a new instance for you hence all properties are nulls.

Try adding contentType: "application/json; charset=utf-8" to your ajax call.

OK, finally figured it out. Here is a full and proper solution showing how to pass additional parameters along with the object:
jQuery:
var myString= "my paramter";
var myObject =
{
Property1: true,
Property2: true
};
var DTO = { param1: myString, param2: myObject };
$.ajax({
contentType: "application/json; charset=utf-8",
type: 'POST',
url: 'myController/StartProcess',
data: JSON.stringify(DTO)
});
Controller:
[HttpPost] // notice this additional attribute!
private async void StartProcess(string param1, myObject param2)
{
// param2 parameters are all true! param1 shows correctly too.
...
}
Class
public class myObject
{
public bool Property1 { get; set; }
public bool Property2 { get; set; }
}

Related

Controller in my MVC project returning null from Ajax Post call

I'm not sure to why the controller is receiving a data from an Ajax call . Could i be doing anything wrong?
[HttpPost]
[Route("Product/UpdateDetails")]
public ActionResult UpdateProduct (ProductModel model) <<// model here is null
{
Product p = new Product
{
ProductId = p.ProductId,
Price = p.Price,
};
return View("_ProductDetail"); }
Ajax call below:
var model = {
ProductId: 1,
Price: 270.99,
};
var json = JSON.stringify(model)
$.ajax({
url: '/Product/UpdateDetails',
type: 'Post',
contentType: "application/json; charset=utf-8",
model: model,
success: function (results) {
}
});
//Model
public class Product
{
public int Id {get;set;}
public double Price {get;set;}
}
Can you guys spot anything that i may be doing wrong in the code above ? I can't see anything that i'm doing wrong.
Try this:
$.ajax({
url: '/Product/UpdateDetails',
type: 'Post',
contentType: "application/json; charset=utf-8",
data: json,
success: function (results) {
}
});
You used JSON.Stringify() on your model, but forgot to use the variable "json" on the ajax call, so the ajax was trying to post a "non-json" model.
Also, there is no model setting in ajax calls, the correct one to post your data is data, as you can see here.

Passing array of integers to webapi Method

I am trying to pass an array of int but I can not get the value in the webapi method
var postData = { "deletedIds": deletedIds };
$.ajax({
type: "DELETE",
traditional: true,
dataType: 'json',
contentType: 'application/json',
cache: false,
url: "/api/Management/Models",
data: JSON.stringify(postData),
success: ModelDeleted,
error: ModelNotDeleted
});
and in apiController :
[HttpDelete]
public bool DeleteModel(int[] deletedIds)
{
return modelsRepository.DeleteModels(deletedIds);
}
Your code looking pretty Ok to me. Please define structure of "deletedIds" object.
one suggestion is to Use
new Array()
object to initialize deletedIds property and remove JSON.stringify() .
A similar question asked here.
EDIT
Web API supports parsing content data in a variety of ways, but it does not deal with multiple posted content values. A solution for your problem could be to create a ViewModel with a property of int[] type.
Like code below,
public class SimpleViewModel
{
public int[] deletedIds{ get; set; }
}
//Controller
[HttpDelete]
public bool DeleteModel(SimpleViewModel deletedIds)
{
return modelsRepository.DeleteModels(deletedIds.deletedIds);
}
and use it as parameter type.
At last, based on #Shashank Answer it worked and the code modified as :
var deletedIds = new Array();
deletedIds.push(modelId);
var postData = { "DeletedIds": deletedIds };
$.ajax({
type: "Delete",
traditional: true,
dataType: 'json',
cache: false,
url: "/api/Management/Models",
data: postData,
success: ModelDeleted,
error: ModelNotDeleted
});
and the apiController :
[HttpDelete]
public bool DeleteModels(DeleteViewModel dvm)
{
return modelsRepository.DeleteModels(dvm.DeletedIds);
}
and for the DeleteViewModel :
public class DeleteViewModel
{
public int[] DeletedIds { get; set; }
}
I suspect that the stringify bit is messing up your object - have you tried assigning it to a variable to see if it's the expected formatting?
You're stringifying the whole thing at the moment:
{ "deletedIds": deletedIds }
while what you probably want to send as post body is this:
{ "deletedIds": JSON.stringify(deletedIds) }

Received parameter from ajax POST empty in controller + passed parameter in firebug MVC 4

I have looked over the net to figure out what my mistake is. All suggestions I found I tried, without any succes. I access the httppost action in my controller but the parameters stays empty.
AJAX function
var dataPost = { 'id': id, 'val': val };
debugger;
$.ajax({
type: 'POST',
url: '/Extensions/UpdateJson',
data: dataPost ,
contentType: 'json',
success: function () {
alert("succes");
},
error: function () {
alert("error");
}
});
On debug DataPost is populated.
Controller
[HttpPost]
public ActionResult UpdateJson(string id, string val)
{
//do stuff
return Json(true);
}
The parameters I used in my controller have the same name as in my Ajax function. The format passed is json, I have also tried populating my data with:
var dataPost = { 'id': 'id', 'val': 'val' };
But this doesn't make any difference. I have also tried to work with a Class, like -->
Class
public class ScheduleData
{
public string id { get; set; }
public string val { get; set; }
}
Controller
public ActionResult UpdateJson(ScheduleData data)
{//Do something}
Any help would be appreciated. Thanks in advance
The format passed is json
No, not at all. You are not sending any JSON. What you do is
data: { 'id': id, 'val': val }
But as the documentation clearly explains this is using the $.param function which in turn uses application/x-www-form-urlencoded encoding.
So get rid of this contentType: 'json' property from your $.ajax call.
Or if you really wanna send JSON, then do so:
var dataPost = { 'id': id, 'val': val };
$.ajax({
type: 'POST',
url: '/Extensions/UpdateJson',
data: JSON.stringify(dataPost),
contentType: 'application/json',
success: function () {
alert("succes");
},
error: function () {
alert("error");
}
});
Things to notice:
usage of JSON.stringify(dataPost) to ensure that you are sending a JSON string to the server
contentType: 'application/json' because that's the correct Content-Type value.

Kendo UI - Ajax MVC - JSON always null

I have a Kendo grid that has been sort-enabled. I want to do an ajax postback using jQuery to send the sort information to the action method to do some action.
var datasource = $(".data-table").data("kendoGrid").dataSource;
$.ajax({
type: 'POST',
url: '#Url.Action("ExportToPDf", "MyController")',
dataType: 'json',
data: { sort: datasource._sort }
});
I'm able to see with a debugger that the correct value is got and passed in the data attribute of the ajax. I used FireBug to confirm that the values are passed during the POST action.
public ActionResult ExportToPDf(List<SortDescription> sort)
{
//Will be doing some action
return null;
}
public class SortDescription
{
public string dir { get; set; }
public string field { get; set; }
}
Sample data from Firebug during POST action
sort[0][dir] asc
sort[0][field] EmployeeRef
When I keep breakpoint in action method, im able to get one item in the list, but the properties appear to be null.
Can anyone please guide me what I do wrong?
Try something like this:
$.ajax({
url: '#Url.Action("ExportToPDf", "MyController")',
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({sort: datasource._sort })
})

MVC ajax json post to controller action method

I am trying to achieve a JQuery AJAX call to a controller action method that contains a complex object as a parameter.
I have read plenty blogs and tried several techniques learned from these. The key post on which I have constructed my best attempt code (below) is the stackoverflow post here .
I want to trigger an asynchronous post, invoked when the user tabs off a field [not a Form save post – as demonstrated in other examples I have found].
My intention is to:
Instantiate an object on the client [not the ViewModel which provides the type for the View];
Populate the object with data from several fields in the view;
Convert this object to JSON;
Call the controller action method using the jQuery.Ajax method, passing the JSON object.
The results will be returned as a JSON result; and data will be loaded into fields in the view depending on results returned.
The problems are:
If the action method is attributed with the HttpPost attribute, the controller Action method is not invoked (even though the AJAX call type is set to ‘POST’).
If the action method isattributed with HttpGet, the values of properties of the parameter are null
The ReadObject method throws the error: "Expecting element 'root' from namespace ''.. Encountered 'None' with name 'namespace'".
Hopefully someone can help. Thanks. Code below:
Client js file
var disputeKeyDataObj = {
"InvoiceNumber": "" + $.trim(this.value) + "",
"CustomerNumber": "" + $.trim($('#CustomerNumber').val()) + ""
};
var disputeKeyDataJSON = JSON.stringify(disputeHeadlineData);
$.ajax({
url: "/cnr/GetDataForInvoiceNumber",
type: "POST",
data: disputeKeyDataJSON,
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: EnrichedDisputeKeyData(result)
});
Action Filter and class for the type associated with the Action method parameter
[DataContract]
public class DisputeKeyData
{
[DataMember(Name = "InvoiceNumber")]
public string InvoiceNumber { get; set; }
[DataMember(Name = "CustomerNumber")]
public string CustomerNumber { get; set; }
}
Action method on the controller
//[HttpPost]
[ObjectFilter(Param = "disputeKeyData", RootType = typeof(DisputeKeyData))]
public ActionResult GetDataForInvoiceNumber(DisputeKeyData disputeKeyData)
{
//Blah!
//....
return Json(disputeKeyData, JsonRequestBehavior.AllowGet);
}
Below is how I got this working.
The Key point was:
I needed to use the ViewModel associated with the view in order for the runtime to be able to resolve the object in the request.
[I know that that there is a way to bind an object other than the default ViewModel object but ended up simply populating the necessary properties for my needs as I could not get it to work]
[HttpPost]
public ActionResult GetDataForInvoiceNumber(MyViewModel myViewModel)
{
var invoiceNumberQueryResult = _viewModelBuilder.HydrateMyViewModelGivenInvoiceDetail(myViewModel.InvoiceNumber, myViewModel.SelectedCompanyCode);
return Json(invoiceNumberQueryResult, JsonRequestBehavior.DenyGet);
}
The JQuery script used to call this action method:
var requestData = {
InvoiceNumber: $.trim(this.value),
SelectedCompanyCode: $.trim($('#SelectedCompanyCode').val())
};
$.ajax({
url: '/en/myController/GetDataForInvoiceNumber',
type: 'POST',
data: JSON.stringify(requestData),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
error: function (xhr) {
alert('Error: ' + xhr.statusText);
},
success: function (result) {
CheckIfInvoiceFound(result);
},
async: true,
processData: false
});

Resources