I'm trying to post data using jQuery Ajax to MVC action using the approach below. But inside the controller all model properties are always null
. Not sure what I'm missing here.
.CSHTML
<form id="MyForm">
<input name="PersonName" type="text" />
<input name="Address" type="text" />
<select name="States" multiple="multiple">
<option value="TX">Texas</option>
<option value="OK">Oklahoma</option>
<option value="OH">Ohio</option>
</select>
<select name="Status">
<option value="1">Active</option>
<option value="2">Deleted</option>
<option value="3">Pending</option>
</select>
<input type="button" value="Save" id="Save" />
JavaScript
$(function () {
$("#Save").click(function (e) {
var dataToPost = $("#MyForm").serialize()
$.ajax(
{
type: "POST",
data: JSON.stringify(dataToPost),
url: "Working/Save",
contentType: 'application/json; charset=utf-8'
})
})
})
Controller
public class WorkingController : Controller
{
// GET: Working
public ActionResult Index()
{
return View();
}
public ActionResult Save(WorkingModel model)
{
// All model properties are null here????
return Json("Success");
}
}
Model
public class WorkingModel
{
public string PersonName { get; set; }
public string Address { get; set; }
public string[] States { get; set; }
public string Status { get; set; }
}
EDIT1
I have added the model above. Here the serialized data and JSON stringify
data when I click on save.
Serialized data
"PersonName=Foo&Address=123+Test+Drive&States=TX&Status=1"
After JSON.Stringify
"\"PersonName=Foo&Address=123+Test+Drive&States=TX&Status=1\""
I have tried adding HttpPost
attribute and [FromBody]
attribute with no luck.
I don't think I have to change the return type from ActionResult
to JsonResult
.
Also the URL is correct because the debugger is hitting inside the action method where I can QuickWatch
the model properties.
Note that it works if I create JSON object and post it like below:
var dataToPost = {
PersonName:'Foo',
Address: '123 Test Drive',
State: 'TX',
Status: 1
}
Below is an example of calling a controller action called "GetData" using javascript/jquery. var url = '@Url. Action("GetData")'; $. ajax({ url: url, type: 'GET', cache: false, data: { value: strId}, success: function (result) { $('#result').
Your JavaScript/jQuery code can be significantly simplified, which might be the best route to go:
$(function () {
$("#MyForm").on('submit', function (e) {
e.preventDefault() // prevent the form's normal submission
var dataToPost = $(this).serialize()
$.post("Working/Save", dataToPost)
.done(function(response, status, jqxhr){
// this is the "success" callback
})
.fail(function(jqxhr, status, error){
// this is the ""error"" callback
})
})
})
You should handle the onsubmit
event of the form, rather than the onclick
event of the button - it's possible for something other than the button to cause the form to be submitted. In this case, we want to prevent the form's default submit behavior, since we're submitting the form with AJAX.
.serialize()
already handles encoding the form correctly, so you don't need to JSON-encode the form values. Doing so is most likely the reason that the modelbinder isn't rebuilding the model when processing the request.
$.post
is a helper function that wraps the common setup work you need for $.ajax
- the version shown here wants the URL to POST to, and the data to POST. If your jQuery code is in a script element within a View, then you probably want to use the Url.Action()
helper - it will build the correct URL based on your routing rules. If you elect to go that route, you would use something similar to:
$.post('@Url.Action("Save", "Working")', dataToPost)
Then, we handle the successful response (anything with a HTTP-200 status code) and the failed response (anything else, basically) using the relevant helpers. What you do in those helpers is up to you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With