I am having a strange issue that is up above my level, I tried to troubleshoot the issue without luck.
I am developing a simple MVC application and I am using ajax to send data from a view to controller. For some reason, the controller only recognized the fist parameters and the rest are just nulls. I even tried to put fixed strings instead of variables but they still appear as null from the controller???
The view:
$.ajax({
type: "POST",
url: "../Home/AddItem",
data: "{ItemModel: 'ttt1', ItemName: 'ttt2'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
console.log(JSON.stringify(data));
if (data.Success == "Success") {
alert("Item has been added.");
} else {
alert("We were not able to create the offer");
}
},
error: function (exception) {
console.log(exception);
}
});
On the Home controller, I have the below action:
[HttpPost]
public JsonResult AddItem(string ItemModel, string ItemName)//ItemName is always null??
{
try
{
_DB.Database.ExecuteSqlCommand(#"INSERT INTO ITEMS(iModel, iName) VALUES ({0}, {1})", ItemModel, ItemName);
return Json(new { Success = "Success" });
}
catch (Exception ex)
{
throw ex;
}
}
You are not sending the data correctly.
The code indicates JSON but is sending just a single string. If you inspect ItemModel, I am certain it will contain the string data sent from the client.
Create a JavaScript object and then stringify that as the body of the request.
var payload = { ItemModel: 'ttt1', ItemName: 'ttt2' }; //<-- create object
$.ajax({
type: "POST",
url: "../Home/AddItem",
data: JSON.stringify(payload), //<-- properly format for request
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
console.log(JSON.stringify(data));
if (data.Success == "Success") {
alert("Item has been added.");
} else {
alert("We were not able to create the offer");
}
},
error: function (exception) {
console.log(exception);
}
});
The model binder should then be able to differentiate the desired parameters.
Ideally when expecting data in the body of a request it is better to use a model
public class Item {
public string ItemModel { get; set; }
public string ItemName { get; set; }
}
And have the action explicitly look for it in the body of the request using the FromBody attribute
[HttpPost]
public JsonResult AddItem([FromBody]Item item) {
if(ModelState.IsValid) {
try {
var sql = #"INSERT INTO ITEMS(iModel, iName) VALUES ({0}, {1})";
_DB.Database.ExecuteSqlCommand(sql, item.ItemModel, item.ItemName);
return Json(new { Success = "Success" });
} catch (Exception ex) {
throw ex;
}
}
return Json(new { Success = "BadRequest" });
}
Related
So on button click there is a function sendEmail(). Alert is working fine, I can see my datas there. But on backend I can't see anything, just everything is null.
function sendEmail() {
var datas = new Object();
datas.mail = $('#contactDropdownList').val();
datas.mailobject = $('#emailObject').val();
datas.text = $('#emailText').val();enter code here
alert(datas.mail + datas.mailobject + datas.text);
$.ajax({
type: "POST",
dataType: "json",
url: "/Email/sendEmail",
contentType: 'application/json; charset=UTF-8',
data: JSON.stringify({ items: datas }),
success: function (data) {
console.log(data);
//do something with data
},
error: function (jqXHR, textStatus, error) {
//log or alert the error
console.log(error);
}
});
}
C# code:
public class MyClass
{
public string Email { get; set; }
public string Object { get; set; }
public string Text { get; set; }
}
[HttpPost]
public IActionResult sendEmail(MyClass items)
{
return Json(new { data="Ok" });
}
items.Email, items.Object and items.Text are null.
And the return valu is null as well, because in javascript success: function (data) { console.log(data);
is empty string.
What can be the problem? Thank you!
Model binder expects json content to match C# class. Your datas object should look like that
var datas = {
email: $('#contactDropdownList').val(),
object: $('#emailObject').val(),
text: $('#emailText').val()
}
Since you wrapped your object ({ items: datas }), you may think it will be mapped to sendEmail(MyClass items), but in reality items name does not matter, you can change variable name to any other name you like
Make sure you apply [FromBody] attribute to your parameter like that
[HttpPost]
public IActionResult sendEmail([FromBody]MyClass items)
Complete demo:
<script>
function sendSmth() {
var data = {
Email: 'email',
Object: 'object',
Text: 'text'
};
$.ajax({
type: "POST",
dataType: "json",
url: "/home/index",
contentType: "application/json",
data: JSON.stringify(data),
success: function (datas) {
console.log(datas)
}
})
}
</script>
And controller
[HttpPost]
public IActionResult Index([FromBody]MyClass obj)
{
return View();
}
As someone has noted, you have a mismatch between what you're sending to the controller and what the model the modelbinder is expecting. You can also vastly simply your AJAX code:
function sendEmail() {
var data = {
Email: $('#contactDropdownList').val(),
Object: $('#emailObject').val(),
Text: $('#emailText').val()
};
$.post("/Email/sendEmail", data)
.done(function (response) {
console.log(response);
//do something with response
})
.fail(function (jqXHR, textStatus, error) {
//log or alert the error
console.log(error);
});
}
You don't really need to specify the content type or data type - the $.post helper's defaults work just fine for what you've shown.
I'm trying to POST an INT with Ajax to my MVC controller.
The script debugging confirms that my variable is an INT with a value (for example 8 and not a string "8"). All lines of code are executed and
I recive my Alert error message.
I've got a breakpoint inside of my Action in the controller but I never get that far. I get a notice in my Action that a request failed, but it only say
"POST Order/Delete". My Controller name is OrderController and Action name is Delete.
My JavaScript:
//Delete order
$(".deleteOrder").on("click", function () {
var id = parseInt($(this).attr("id"));
if (id !== null) {
$.ajax({
url: "/Order/Delete",
method: "POST",
contentType: "application/JSON;odata=verbose",
data: id ,
success: function (result) {
alert("Ok")
},
error: function (error) {
alert("Fail");
}
});
}
});
My MVC Action
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id)
{
List<OrderRow> lstOrderRow = new List<OrderRow>();
lstOrderRow = db.OrderRows.Where(x => x.OrderId == id).ToList();
foreach(var row in lstOrderRow)
{
db.OrderRows.Remove(row);
}
Order order = new Order();
order = db.Orders.Find(id);
db.Orders.Remove(order);
db.SaveChanges();
return RedirectToAction("index");
}
You should either use the url like this by removing data field
url: "/Order/Delete/" + id,
or send the id in data as below
data: {id: id},
This works for me:data: JSON.stringify({ id: id})
dataType: "json",
contentType: 'application/json; charset=utf-8',
I am learning web development. And I just want to make a simple AJAX GET call in ASP.Net MVC Application and I want visualize how it works. But I am not able to do so. I am a beginner and I could have done any silly mistakes. But as of now there are no errors in my code.
Below is what I have:
So, I have a Index.cshtml file which is already loaded. Now in that page I want to make an Ajax GET call to one of the function that I have written in the HomeController and action name is Test. I just want to hit the breakpoint in that Test Action of Homecontroller and return something back to the Success of AJAX Call.
In HomeController I have below Action
[HttpGet]
public ActionResult Test()
{
return View("hello");
}
jQuery
$.ajax({
url: '/Home/Test',
type: 'GET',
success: function (html) {
alert(html);
},
error: function (error) {
$(that).remove();
DisplayError(error.statusText);
}
});
}
Confusion: Do I need to create a cshtml for Test. But I actually do not want that. I just want the Test Action to return me one data. And I will display that data in my Already opened Index.csthml file.
Error: No error but I am not able to hit the breakpoint in Test Action of controller. Kindly note that Success of AJAX is hitting but I do not see any data. But I am sure it did not hit the test Action breakpoint.
Change your action method like this
[HttpGet]
public JsonResult Test()
{
return Json("myContent",JsonRequestBehavior.AllowGet);
}
And in your success method in 'html' variable you will get back "myContent".
Example :
function RemoveItem(ItemId) {
if (ItemId && ItemId > 0) {
$.ajax({
cache: false,
url: '#Url.Action("RemoveItem", "Items")',
type: 'POST',
data: { id: ItemId },
success: function (result) {
if (result.success == true) {
$("#CartItemGridDiv").load('#Url.Content("~/User/Items/CartItemGrid")');
alert('Item Removed successfully.');
}
else {
alert('Item not removed.');
}
},
error: function (result) {
alert('Item not removed.');
}
});
}
}
public ActionResult RemoveItem(int id)
{
if (id > 0)
{
bool addToChart = false;
addToChart = Utilities.UtilityClass.RemoveItem(id);
if (addToChart)
{
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
}
return Json(new { success = false }, JsonRequestBehavior.AllowGet);
}
public ActionResult CartItemGrid()
{
List<CartItems> oItemList = (List<CartItems>)Session[MvcMAB.StringConst.CartItemSession];
return View(oItemList);
}
Since you don't want to return a view, you might need to return Json() instead of View()
You need to Allow Get in the action. Like that:
public ActionResult SomeGetAction(int? id)
{
//Some DB query here
var myJsonList = myListQuery;
return Json(myJsonList, JsonRequestBehavior.AllowGet);
}
Or in case of just Simple string response:
public ActionResult SomeGetAction()
{
return Json("My String", JsonRequestBehavior.AllowGet);
}
I would recommend renaming html into response.
Also change that to this in Error Response section.
$.ajax({
url: '/Home/Test',
type: 'GET',
success: function (response) {
alert(response);
},
error: function (error) {
$(this).remove();
DisplayError(error.statusText);
}
});
Enjoy.
C#:
public JsonResult Test()
{
return Json("hello");
}
Jquery:
$.ajax({
url: '/Home/Test',
type: 'Post',
dataType: 'json',
success: function (html) {
alert(html);
},
error: function (error) {
alert(error);
}
});
$("#modelchange").change(function() {
$.ajax({
type: 'POST',
url: '#Url.Action("GetStore")',
dataType: 'json',
data: {
Id: $("#modelchange").val()
},
success: function(storeName) {
$('#storeName').text("Store : " + storeName);
},
error: function(ex) {
alert('Failed to load store Value');
}
});
return false;
});
API
[HttpPost]
public string GetStore(int Id)
{
string storeName = db.AddInktoStores.Single(a => a.InkId == Id)).Store.StoreName;
return storeName;
}
Above mentioned is a controller and JSON in my javascript.
I am trying to get Store Name but I keep getting throw into my error: function
Please Help!
Try to return data as:
[HttpPost]
public JsonResult GetStore(int Id)
{
string storeName = db.AddInktoStores.Single(a => a.InkId == Id)).Store.StoreName;
return Json(storeName);
}
I am passing my list to an mvc controller but I am getting null value in the controller.But my list has values when show in alert on client side.
ajax call
$("#addTiles").click(function() {
userTiles = JSON.stringify({
'userTiles': userTiles
});
alert("Entered function.");
alert(userTiles[0].TileID);
var url = '#Url.Action("AddTiles")';
$.ajax({
type: "GET",
url: url,
data: userTiles,
success: function(d) {
if (d.indexOf('"IsSessionExpired":true') != -1) {
location.reload();
} else {
onAddTilesSuccessful(d);
}
},
error: function() {
errorInOperation();
},
contentType: "application/html; charset=utf-8",
dataType: 'html'
});
});
function onAddTilesSuccessful(e) {
$("#tilesSubmissionMsg").append(e);
}
function errorInOperation(d) {
$("#tilesSubmissionMsg").append("Something went wrong");
}
mvc controller
public ActionResult AddTiles(List<UserTilesVM> userTiles)
{
return View();
}
List Model
public class UserTilesVM
{
public int TileID { get; set; }
public int TopPosition { get; set; }
public int LeftPosition { get; set; }
}
List in javascript
"{"userTiles":[{"TileID":"3","TopPosition":0,"LeftPosition":0}]}"
I have also tried by sending my list with stringfy but that also doesn't work.
Use : [HttpGet] on the method AddTiles as you have used type: "GET" on the Ajax hit.
[HttpGet]
public ActionResult AddTiles(List<UserTilesVM> userTiles)
{
return View();
}
If Still doesn't works then try type: "POST" on Ajax hit and on method use [HttpPost]
[HttpPost]
public ActionResult AddTiles(List<UserTilesVM> userTiles)
{
return View();
}
You have contentType and dataType twice in your AJAX setup, with different values, which will break the AJAX call.
Keep in mind contentType is to tell the server what type of data to expect and dataType is to determine what type of data is returned, from the documentation.
Edit: I see you have edited your code!
In this case, since you are using JSON.Stringify to modify the data you are sending, you would use contentType: "application/json; charset=utf-8", as your contentType, since you are sending JSON data to the backend.
when we are trying to pass object data using ajax, we have to store data in variable and pass data directly using "data :'variable'" in AJAX to Controller Method
$("#addTiles").click(function() {
var userTiles = ({
'userTiles': userTiles
});
alert("Entered function.");
alert(userTiles[0].TileID);
var url = '#Url.Action("AddTiles")';
$.ajax({
type: "POST",
url: url,
data: userTiles,
success: function(d) {
if (d.indexOf('"IsSessionExpired":true') != -1) {
location.reload();
} else {
onAddTilesSuccessful(d);
}
},
error: function() {
errorInOperation();
},
contentType: "application/html; charset=utf-8",
dataType: 'html'
});
});
function onAddTilesSuccessful(e) {
$("#tilesSubmissionMsg").append(e);
}
function errorInOperation(d) {
$("#tilesSubmissionMsg").append("Something went wrong");
}
//Use [HttpPost] keyword for getting value which was passed by AJAX.
[HttpPost]
public ActionResult AddTiles(List<UserTilesVM> userTiles)
{
return View();
}
I think your list definition is not ok:
"{"userTiles":[{"TileID":"3","TopPosition":0,"LeftPosition":0}]}"
should be:
"{"userTiles":[{"TileID":"3","TopPosition":"0","LeftPosition":"0"}]}"
i have using this sequence that work fine
you have check the
contentType: "application/json",
dataType: "json",
sequence in ajax method