Unable to pass values to MVC Controller via AJAX - c#

I have an MVC controller which takes an int and a complex object
[HttpPost]
public async Task<JsonResult> AddComment(int ticketId, TicketReply ticketReply)
Even if I take out the object, I can't seem to pass a simple value. Here's what the AJAX call looks like
var dataObject = {
ticketId: ticketId //, ticketReply: { Attachements: attachements }
};
$.ajax({
url: $('#updateTicketURL').val(),
data: dataObject, //, //JSON.stringify(dataObject), //JSON.stringify(dataObject),
type: 'POST',
//dataType: 'JSON',
contentType: 'application/json',
success: function (data) {
console.log(data);
}
})
I have tried every combination of JSON.stringyfy etc. but I never seem to get the value. Even if I replace with static values it never seems to work.

You need an object model that matches the data being sent
public class DataObject {
public int ticketId { get; set; }
public TicketReply ticketReply { get; set; }
}
next you update the controller action to expect the data using the [FromBody] attribute so that the model binder can create and populate the sent data
[HttpPost]
public async Task<JsonResult> AddComment([FromBody]DataObject dataObject) {
int ticketId = dataObject.ticketId;
TicketReply ticketReply = dataObject.ticketReply;
//...
}
Finally you need to send the data correctly from the client.
var dataObject = {
ticketId: ticketId ,
ticketReply: { Attachements: attachements }
};
$.ajax({
url: $('#updateTicketURL').val(),
data: JSON.stringify(dataObject),
type: 'POST',
dataType: 'JSON',
contentType: 'application/json',
success: function (data) {
console.log(data);
}
});

Related

Ajax call is posting 0 or null

Can't figure out this simple ajax call.
The controller successfully returns the json file as it should, but is logging two zeroes as the values for both the country and amount, which are incorrect. What am I doing wrong here?
controller:
[HttpPost("search")]
public IActionResult test(int country, int amount)
{
System.Console.WriteLine(country);
System.Console.WriteLine(amount);
return Json("success : true");
}
jQuery:
var data = "{ 'country': 2, 'amount': 4}";
$.ajax({
url: "search",
type: "POST",
data: data,
cache: false,
contentType: "application/json",
success: function (data) {
alert("hi"+ data);
}
});
Create a model to hold the desired values
public class TestModel {
public int country { get; set; }
public decimal amount { get; set; }
}
Update the action to expect the data in the body of the request using [FromBody] attribute
[HttpPost("search")]
public IActionResult test([FromBody]TestModel model) {
if(ModelState.IsValid) {
var country = model.country;
var amount = model.amount;
System.Console.WriteLine(country);
System.Console.WriteLine(amount);
return Ok( new { success = true });
}
return BadRequest(ModelState);
}
Client side you need to make sure the data is being sent in the correct format
var data = { country: 2, amount: 4.02 };
$.ajax({
url: "search",
type: "POST",
dataType: 'json',
data: JSON.stringify(data),
cache: false,
contentType: "application/json",
success: function (data) {
alert("hi"+ data);
}
});
Reference Model Binding in ASP.NET Core
You should use JSON.stringify to convert a object into a json string. Do not try to use string concatenation to do this.
Your types for amount do not match what you are sending. A money type should probably be decimal in c#.
Return an anonymous object from the c# method as well and pass that to Json.
The content-type is incorrect, see also What is the correct JSON content type?
[HttpPost("search")]
public IActionResult test(int country, decimal amount)
{
System.Console.WriteLine(country);
System.Console.WriteLine(amount);
// return an anymous object instead of a string
return Json(new {Success = true});
}
jQuery:
var data = JSON.stringify({country: 2, amount: 4.02});
$.ajax({
url: "search",
type: "POST",
dataType: 'json',
data: data,
cache: false,
contentType: "application/json",
success: function (data) {
alert("hi"+ data);
}
});
What am I doing wrong here?
dataType is not required so you can omit that.
4.02 is not an int so you should probably replace that with decimal
and contentType should be application/json
Thanks everyone! Got it working with your help.
It won't work after I remove [FromBody]
[HttpPost("search")]
public IActionResult test([FromBody] string data)
{
System.Console.WriteLine(data);
return Json(new {Success = true});
}
jQuery:
var data = JSON.stringify("{ 'data': 'THOMAS' }");
$.ajax({
url: "search",
type: "POST",
data: data,
cache: false,
contentType: "application/json",
success: function (data) {
alert("hi"+ data);
}
});

pass value to controller by using ajax

I want to pass value from view to controller by using ajax.
<button onclick="addCommentByAjax()" >Save</button>
My script:
function addCommentByAjax() {
$.ajax({
type: "POST",
url: '/Survey/DoDetailSurvey',
data: {
choiceId: "1"
}
});
}
Controller:
[HttpPost]
public ActionResult DoDetailSurvey(SurveyViewModel model, string choiceId)
{
//
}
but choiceId always null
Change couple of things.
First assign an id or class to your button.Second remove inline onclick function and use ajax click function.Then specify the request type as Post.
$('#btnComment').click(function () {
var choiceId = $('#YourChoiceId').val();
$.ajax({
url: '/Survey/DoDetailSurvey',
data: { 'choiceId' : choiceId},
type: "post",
cache: false,
success: function (response) {
//do something with response
},
error: function (xhr, ajaxOptions, thrownError) {
alert('error occured');
}
});
});
Then your controller should look like this
[HttpPost]
public ActionResult DoDetailSurvey(string choiceId)
{
//
}
I don't know how you are populating your viewmodel,so I purposely removed them and shown an working example.
In case you want to pass viewmodel you should construct your data object like this:
var data = {};
data.Property1 = some val;
data.Property2 = "some val";
$.post('/Survey/DoDetailSurvey', data);
Sample structure of SurveyViewModel I assume:
public class SurveyViewModel
{
public int Property1 { get; set; }
public string Property2 { get; set; }
}
Since there are two parameter in your controller, you need to identify them both form the client side. Further, you should specify the contentType.
You spread the payload like so:
function addCommentByAjax() {
var payload = {
model: {
// whatever properties you might have
},
choiceId: 1
};
$.ajax({
type: "POST",
url: '/Survey/DoDetailSurvey',
contentType: 'application/json',
data: JSON.stringify(payLoad)
});
}
function addCommentByAjax() {
$.ajax({
type: "POST",
url: '/Survey/DoDetailSurvey?choiceId=1'
}
});
}
You can also pass like this
or for more parameters
function addCommentByAjax() {
$.ajax({
type: "POST",
url: '/Survey/DoDetailSurvey?choiceId=1&Name=Arun'
}
});
}

How to send javascript dictionary to controller method in MVC4

I have a js file that has to send a dictionary object to the server. My javascript part looks like that:
$.ajax({
url: "/ControllerName/ActionName",
type: 'post',
dataType: 'json',
data: myData
});
where myData is something like
this myData["favouritePet"] = "dog", myData["favouriteBook"] = "What?"
In the controller I have this:
[HttpPost]
public virtual ActionResult ActionName ( Dictionary<string, string> jsonFormattedData)
{
return null;
}
but when I debug it the parameter gets a null value every time. I tried to make the argument of type string but it is the same. Can you help me with that?
You are just passing JavaScript object, so you can use JSON.stringify and make the Model as Action parameter.
MVC Model Binder will convert it to your model.
public class MyDataModel
{
public string FavouritePet { get; set; }
public string FavouriteBook { get; set; }
}
// GET: Home
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(MyDataModel myData)
{
return View();
}
<button id="btnSubmit" type="button">Submit</button>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
$("#btnSubmit").click(function () {
var myData = new Object();
myData.favouritePet = "dog";
myData.favouriteBook = "What?";
$.ajax({
url: '#Url.Action("Index", "Home")',
type: 'POST',
dataType: 'json',
data: JSON.stringify(myData),
contentType: "application/json; charset=utf-8",
success: function (){}
});
});
</script>

How exactly does a JSON.stringify automatically map to my DTO

I have an object in jquery:
function SaveRequest() {
var request = BuildSaveRequest();
$.ajax({
type: "POST",
processData: false,
data: JSON.stringify({'model':request}),
url: "somepage.aspx/JsonSave",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(response, status, xhr) {
},
error: function (res, status, exception) {
}
});
return false;
}
function BuildSaveRequest() {
var request = {
customerName: $("#CustomerName").val(),
contactName: $("#ContactName").val(),
};
return request;
}
And I have the following c# code:
[WebMethod]
public static string JsonSave(MyModel model)
{
}
}
public class MyModel
{
public string CustomerName { get; set; }
public string ContactName { get; set; }
}
When the ajax call goes, the web method JsonSave automatically place the values (CustomerName, & ContactName) from the jquery object 'request' into the appropriate properties in object 'model'. How does it know to do that???
Added answer from comments:
Model Binders are a beautiful thing.
I would recommend reading the source found here this is for MVC but I'm pretty sure it acts the same in webforms as well.
It is really smart and checks the in request for the data so it doesn't really matter if you use webforms or mvc. You can even create our own.

data posted with jquery post to Asp.net 4 Mvc 2 as null

I am using jquery 1.8 to post data to ASP.Net 4 MVC 2 like this
PostData('Home/Login',{ "username": $("#username").val(),"password": $("#password").val()})
function PostData(url, data) {
$.ajax({
url: url,
data:data,
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
Success:successFunction, Error: ErrorFunction
});
};
My model
namespace FmsMvc.Models
{
public class UsersModel
{
public int UserID { get; set; }
public string Role { get; set; }
public string Email { get; set; }
public DateTime ts { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
}
My Controller
[HttpPost]
public JsonResult Login(UsersModel u)
{
if (doSomething(Prop1, Prop2)
return Json(null); // Success
return Json(new { Status:'success',Msg:" Your username"+u.username });
}
My controller does not get the data. It gets null when debugging.
what am i doing wrong?
NOTE
I deleted all the javascript in the Scripts folder, as I am using a custom script
Have you tried JSON.strinfigy-ing your data before POSTing?
function PostData(url, data) {
$.ajax({
url: url,
data:JSON.stringify(data),
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
Success:successFunction, Error: ErrorFunction
});
};
Try it like this:
var data = { "username": $("#username").val(),
"password": $("#password").val()
};
PostData('Home/Login',JSON.stringify(data));
You can use the JQuery .post() method which will parse the values for you
var url = '#Url.Action("Login", "Home")'; // beter to use this rather than hardcoding
var userName = `$("#username").val();
var password = $("#password").val();
$.post(url, { Username: userName, Password: password }, function(result) {
// do something with the result you returned from the action method
alert(result.Msg);
});
Note, only properties Username and Password will be set in the model. The other properties will be their default values.
After much debugging, i found the culprit
in my ajax function above i have this two line
contentType: 'application/json; charset=utf-8',
dataType:'json',
Somehow, this should not be. when i submitted the form with the two lines present, this is what i saw in chrome dev
But when i removed the line contentType: 'application/json; charset=utf-8', so that the $.ajax is now
$.ajax({ // create an AJAX call...
type: 'post', // GET or POST
url: url, // the file to call
dataType:'json',
data: data, // get the form data
Success:successFunction, Error: ErrorFunction
});
when i look in chrome dev after submit, i see this, which was not there before
I dont' know why this is the case, i will try in other browsers to see if it all works

Categories

Resources