Asked by:
Where did the run time take it? AJAX

Question
-
User1453549677 posted
The AppendRow method is not being executed. I am assuming it's somewhere in the AJAX call below. There is no error, it just goes to sleep. Can anyone see what I've missed? Thanks.
+++++++++++++++++++++++++++++++++ Default.aspx +++++++++++++++++++++++++++
$(document).ready(function () {
getProducts();
$("#btn").on('click', function () {
//1.
//var order = {
// "CustomerName": "MS"
//};
//2.
var prodDTO = [
{ "Id": "4", "Name": "Guava Mango Drink", "Category": "Beverages", "Price": "1.50" },
];
//3.
$.ajax({
url: '/api/products/AppendRow',
type: 'POST',
//4.
data: {
//order: order,
prodDTO: prodDTO
},
ContentType: 'application/json;utf-8',
datatype: 'json'
}).done(function (resp) {
alert("Successful " + resp);
}).error(function (err) {
alert("Error " + err.status);
});
});
return false;
});+++++++++ Product.cs +++++++++++++++++++++++
using Newtonsoft.Json;
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
//public class ProductDTO
//{
//public int Id { get; set; }
//public string Name { get; set; }
//public string Category { get; set; }
//public double Price { get; set; }
//}
public class YourObjectDto
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("category")]
public string Category { get; set; }
[JsonProperty("price")]
public double Price { get; set; }
}
++++++++++++++++++++++++++++++++++++++ ProductsController.cs +++++++++++++++++++++++++++++namespace WebForms
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
};
public IEnumerable<Product> GetAllProducts()
{
return products;
}
public Product GetProductById(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return product;
}
public IEnumerable<Product> GetProductsByCategory(string category)
{
return products.Where(
(p) => string.Equals(p.Category, category,
StringComparison.OrdinalIgnoreCase));
}
public string AppendRow([FromBody] YourObjectDto eventDto)
{
var id = eventDto.Id;
var name = eventDto.Name;
var category = eventDto.Category;
var price = eventDto.Price;
return "success";
}
}
}Thursday, December 21, 2017 11:02 PM
All replies
-
User475983607 posted
There is no indication in your code that a button with the id="btn" exists. Verify that the view contains a button with id="btn"..
The ProdDto object has issues... First the object is defined here as an array containing a single item.
var prodDTO = [ { "Id": "4", "Name": "Guava Mango Drink", "Category": "Beverages", "Price": "1.50" }, ];
The array is assigned to the prodDTO argument in the AJAX method yet the AppendRow expects a single item of type YourObejctDto named eventDto. The name and the type do not match.
data: { //order: order, prodDTO: prodDTO },
public string AppendRow([FromBody] YourObjectDto eventDto) { var id = eventDto.Id; var name = eventDto.Name; var category = eventDto.Category; var price = eventDto.Price; return "success"; }
Basically, you have a lot of errors in the code. I would start by writing debug information to the console. This is a great a great way to get feedback about what's going on in your code.
The following code snippet will write a message if the button id="btn" is clicked. If you do not see the message after clicking the button then there is probably an issue with the jQuery event selector.
You can find the console is in your browser's dev tools. Press F12 in your favorite browser to open dev tools then find and open the console.
$("#btn").on('click', function () { console.log("You clicked the btn Button");
Once you get the event worked out, take a closer look at the rest of your code and try fixing the obvious issues. If you are stillhaving issues, set a break point in the JavaScript and step through the code.
https://developers.google.com/web/tools/chrome-devtools/javascript/breakpoints
Thursday, December 21, 2017 11:34 PM -
User1453549677 posted
My apologies for not posting the complete code. Here it is with a few changes that I've made. It now runs to the AppendRow method but eventDto is null in it. What should be the correction? Thanks for your help.
+++++++++++++++++++++++++++++++++++ Default.aspx +++++++++++++++++++++++++++
namespace WebForms
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
};
public IEnumerable<Product> GetAllProducts()
{
return products;
}
public Product GetProductById(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return product;
}
public IEnumerable<Product> GetProductsByCategory(string category)
{
return products.Where(
(p) => string.Equals(p.Category, category,
StringComparison.OrdinalIgnoreCase));
}
public string AppendRow([FromBody] YourObjectDto eventDto)
{
var id = eventDto.Id;
var name = eventDto.Name;
var category = eventDto.Category;
var price = eventDto.Price;
return "success";
}
}
}++++++++++++++++++++++++++++++++++++++ Product.cs ++++++++++++++++++++++++++++++++++++
using Newtonsoft.Json;
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
public class YourObjectDto
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("category")]
public string Category { get; set; }
[JsonProperty("price")]
public double Price { get; set; }
}+++++++++++++++++++++++++++++++++++ ProductsController.cs +++++++++++++++++++++++++
namespace WebForms
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
};
public IEnumerable<Product> GetAllProducts()
{
return products;
}
public Product GetProductById(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return product;
}
public IEnumerable<Product> GetProductsByCategory(string category)
{
return products.Where(
(p) => string.Equals(p.Category, category,
StringComparison.OrdinalIgnoreCase));
}
public string AppendRow([FromBody] YourObjectDto eventDto)
{
var id = eventDto.Id;
var name = eventDto.Name;
var category = eventDto.Category;
var price = eventDto.Price;
return "success";
}
}
}Friday, December 22, 2017 12:57 AM -
User475983607 posted
A null action method parameter usually means there is a name or type mismatch between the AJAX payload and action method. Assuming you have not changed the JavaScript/AJAX method, you are still passing an array to an action method that accepts a scalar value.
Please try to debug your code. If you require a code review or debugging assistance, please post all the relevant bits so we do not have to guess what state the code base is in.
Friday, December 22, 2017 1:29 AM -
User1453549677 posted
I changed the sending object to a DTO. It's not executing the AppendRow method in ProductsController. Here's the changed code, all else is the same. I h...ope that I'm getting closer.
$(document).ready(function () {
getProducts();
$("#btn").on('click', function () {************* change **********************************
var prodDTO = new YourObjectDto()
{
Id : txtId.Text;
Name : txtName.Text;
Category : txtCategory.Text;
Price : txtPrice.Text;
}
*************************************************************
//3.
$.ajax({
url: '/api/products/AppendRow',
type: 'POST',
//4.
data: {
//order: order,
eventDto: prodDTO
},
ContentType: 'application/json;utf-8',
datatype: 'json'
}).done(function (resp) {
alert("Successful " + resp);
}).error(function (err) {
alert("Error " + err.status);
});
});
return false;
});
//});
var products = ""; //global variable products
function getProducts() {
$.getJSON("api/products",
function (data) {
$('#products').empty(); // Clear the table body.
//Assign the return value to products variable
products = data;
// Loop through the list of products.
$.each(data, function (key, val) {
// Add a table row for the product.
var row = '<td>' + val.Name + '</td><td>' + val.Price + '</td>';
$('<tr/>', { html: row }) // Append the name.
.appendTo($('#products'));
});
});
};
return false;
};
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<h2>Products</h2>
<table>
<thead>
<tr><th>Name</th><th>Price</th></tr>
</thead>
<tbody id="products">
</tbody>
</table>
Id:
<asp:TextBox runat= "server" id="txtId"></asp:TextBox>
Name:
<asp:TextBox runat= "server" id="txtName"></asp:TextBox>
Category:
<asp:TextBox runat= "server" id="txtCategory"></asp:TextBox>
Price:
<asp:TextBox runat= "server" id="txtPrice"></asp:TextBox>
<%--<asp:Button runat ="server" ID="ButtonTest" />--%>
</div>
<p>
<asp:Button runat ="server" ID="btn" Text="POST" OnClick="btn_Click" />
</p>
</form>
</body>
</html>Friday, December 22, 2017 2:11 AM -
User475983607 posted
drl
I changed the sending object to a DTO. It's not executing the AppendRow method in ProductsController. Here's the changed code, all else is the same. I h...ope that I'm getting closer.That is the expected behavior as the ASP Button does a full post and invokes the server side btn_Click handler.
<asp:Button runat ="server" ID="btn" Text="POST" OnClick="btn_Click" />
Change the ASP button to an HTML button. Keep in mind that the Server side handler will not longer be invoked as you are invoking a client side POST.
<input id="btn" type="button" value="POST" />
If you are using dev tools as strongly suggested above, you are seeing button clicks doing a full post to the aspx page and not the API. That should be a clear indication that something is wrong.
Also if you were using dev tools, as suggested above, you would see syntax errors in the console when the page loads. These errors are around "return false" You must fix all the open script errors before moving forward. Please start using dev tools to debug your work so you are not posting code with syntax errors.
With that being said, once I fixed the visible console errors that I found just loading the page, I noticed this syntax error.
var prodDTO = new YourObjectDto() { Id: txtId.Text; Name: txtName.Text; Category: txtCategory.Text; Price: txtPrice.Text; }
I believe you want syntax like below since this an ASP Web Form.
var data = {} data.Id = $('# <%=txtId.ClientID %>').val(); data.Name = $('# <%=txtName.ClientID %>').val(); data.Category = $('# <%=txtCategory.ClientID %>').val(); data.Price = $('# <%=txtPrice.ClientID %>').val();
This is where I stopped debugging as there can be many other errors. This was the first we see you are using Web Forms with Web API. I'm afraid, there could be CORS errors which you are not aware of since it seems you are not debugging the code.
Friday, December 22, 2017 12:35 PM -
User1453549677 posted
mgebhard, thanks for your reply. I used the dev tools to get rid of the syntax errors as you suggested. I ran the program and put a breakpoint just after the
AppendRow Method declaration in the ProductsController.cs page. The eventDto object is nulls and zeros so the data is not going across in the Ajax call. you spot what the problem is? This is my first time working with Ajax and WebApI. Thanks for your expertise.
Here's the current Default.aspx: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebAPI_SPA5.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
$(document).ready(function () {
getProducts();
$("#btn").on('click', function () {
var prodDTO = {}
prodDTO .Id = $('#<%=txtId.ClientID%>').val();
prodDTO .Name = $('#<%=txtName.ClientID%>').val();
prodDTO .Category = $('#<%=txtCategory.ClientID%>').val();
prodDTO .Price = $('#<%=txtPrice.ClientID%>').val();
$.ajax({
url: '/api/products/AppendRow',
type: 'POST',
//4.
data: {
eventDto: prodDTO
},
ContentType: 'application/json;utf-8',
datatype: 'json'
}).done(function (resp) {
alert("Successful " + resp);
}).error(function (err) {
alert("Error " + err.status);
});
return false;
});
var products = ""; //global variable products
function getProducts() {
$.getJSON("api/products",
function (data) {
$('#products').empty(); // Clear the table body.
//Assign the return value to products variable
products = data;
// Loop through the list of products.
$.each(data, function (key, val) {
// Add a table row for the product.
var row = '<td>' + val.Name + '</td><td>' + val.Price + '</td>';
$('<tr/>', { html: row }) // Append the name.
.appendTo($('#products'));
});
});
};
function appendItem() {
var obj = products;
obj.push({ "Id": "4", "Name": "Goya Guava Drink", "Category": "Beverages", "Price": "1.50" });
//if you want to display the change in table then you need to repopulate the table here
$('#products').empty();
// Loop through the list of products.
$.each(obj, function (key, val) {
// Add a table row for the product.
var row = '<td>' + val.Name + '</td><td>' + val.Price + '</td>';
$('<tr/>', { html: row }) // Append the name.
.appendTo($('#products'));
});
return false;
};
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<h2>Products</h2>
<table>
<thead>
<tr><th>Name</th><th>Price</th></tr>
</thead>
<tbody id="products">
</tbody>
</table>
Id:
<asp:TextBox runat= "server" id="txtId"></asp:TextBox>
Name:
<asp:TextBox runat= "server" id="txtName"></asp:TextBox>
Category:
<asp:TextBox runat= "server" id="txtCategory"></asp:TextBox>
Price:
<asp:TextBox runat= "server" id="txtPrice"></asp:TextBox>
</div>
<p>
<input id="btn" type="button" value="POST" />
</p>
</form>
</body>
</html>+++++++++++++++++++++++++ and here again is the AppendRow method from ProductsController
public string AppendRow([FromBody] YourObjectDto eventDto)
{
var id = eventDto.Id;
var name = eventDto.Name;
var category = eventDto.Category;
var price = eventDto.Price;
return "success";
}
Saturday, December 23, 2017 3:40 AM -
User475983607 posted
Verified code...
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="WebFormsDemo._default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Default</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <%--<script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script> <script src="Scripts/jquery-ui-1.12.1.js"></script>--%> <script src="https://code.jquery.com/jquery-1.9.1.js"></script> <script type="text/javascript"> $(document).ready(function () { getProducts(); $("#btn").on('click', function () { var prodDTO = {} prodDTO.Id = $('#<%=txtId.ClientID%>').val(); prodDTO.Name = $('#<%=txtName.ClientID%>').val(); prodDTO.Category = $('#<%=txtCategory.ClientID%>').val(); prodDTO.Price = $('#<%=txtPrice.ClientID%>').val(); $.ajax({ url: 'http://localhost:56689/api/products', type: 'POST', //4. data: prodDTO, ContentType: 'application/json;utf-8', datatype: 'json' }).done(function (resp) { console.log(resp); }).error(function (err) { console.log("Error " + err.status); }); return false; }); var products; //global variable products function getProducts() { $.getJSON("http://localhost:56689/api/products", function (data) { $('#products').empty(); // Clear the table body. //Assign the return value to products variable products = data; // Loop through the list of products. $.each(data, function (key, val) { // Add a table row for the product. var row = '<td>' + val.Name + '</td><td>' + val.Price + '</td>'; $('<tr/>', { html: row }) // Append the name. .appendTo($('#products')); }); }); }; function appendItem() { var obj = products; obj.push({ "Id": "4", "Name": "Goya Guava Drink", "Category": "Beverages", "Price": "1.50" }); //if you want to display the change in table then you need to repopulate the table here $('#products').empty(); // Loop through the list of products. $.each(obj, function (key, val) { // Add a table row for the product. var row = '<td>' + val.Name + '</td><td>' + val.Price + '</td>'; $('<tr/>', { html: row }) // Append the name. .appendTo($('#products')); }); return false; }; }); </script> </head> <body> <form id="form1" runat="server"> <div> <h2>Products</h2> <table> <thead> <tr> <th>Name</th> <th>Price</th> </tr> </thead> <tbody id="products"> </tbody> </table> <hr /> Id: <asp:TextBox runat="server" ID="txtId">10</asp:TextBox> Name: <asp:TextBox runat="server" ID="txtName">Test</asp:TextBox> Category: <asp:TextBox runat="server" ID="txtCategory">Test Category</asp:TextBox> Price: <asp:TextBox runat="server" ID="txtPrice">5.50</asp:TextBox> </div> <p> <input id="btn" type="button" value="POST" /> </p> </form> </body> </html>
// POST api/Products public Product Post([FromBody]Product prodDTO) { return prodDTO; }
public class Product { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal Price { get; set; } }
Saturday, December 23, 2017 1:52 PM -
User1453549677 posted
mgebhard, I used your code... I'm getting a HTTP 500 error. The alerts that I put in are firing correctly. But I put a breakpoint in the Post method in ProductsController.cs. It didn't stop at the breakpoint which seems to indicate that the routing wasn't right. My intention is to have the Post method add the new row to the array and have the new row displayed in the list. Here is the current state of the code:
++++++++++++++++++++++++++++++++++ Default.aspx +++++++++++++++++++++++++++++++++
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebAPISPA6.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Default</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"/>
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
$(document).ready(function () {
getProducts();
$("#btn").on('click', function () {
var prodDTO = {}
alert('on click');
prodDTO.Id = $('#<%=txtId.ClientID%>').val();
prodDTO.Name = $('#<%=txtName.ClientID%>').val();
prodDTO.Category = $('#<%=txtCategory.ClientID%>').val();
prodDTO.Price = $('#<%=txtPrice.ClientID%>').val();
$.ajax({
url: 'http://localhost:65472/api/products',
type: 'POST',
//4.
data: prodDTO,
ContentType: 'application/json;utf-8',
datatype: 'json'
}).done(function (resp) {
console.log(resp);
}).error(function (err) {
console.log("Error " + err.status);
});
alert("Post on click");
return false;
});
var products; //global variable products
function getProducts() {
$.getJSON("http://localhost:65472/api/products",
function (data) {
$('#products').empty(); // Clear the table body.
//Assign the return value to products variable
products = data;
// Loop through the list of products.
$.each(data, function (key, val) {
// Add a table row for the product.
var row = '<td>' + val.Name + '</td><td>' + val.Price + '</td>';
$('<tr/>', { html: row }) // Append the name.
.appendTo($('#products'));
});
alert('exiting getproducts');
});
};
//function appendItem() {
// var obj = products;
// obj.push({ "Id": "4", "Name": "Goya Guava Drink", "Category": "Beverages", "Price": "1.50" });
// //if you want to display the change in table then you need to repopulate the table here
// $('#products').empty();
// // Loop through the list of products.
// $.each(obj, function (key, val) {
// // Add a table row for the product.
// var row = '<td>' + val.Name + '</td><td>' + val.Price + '</td>';
// $('<tr/>', { html: row }) // Append the name.
// .appendTo($('#products'));
// });
// return false;
//};
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<h2>Products</h2>
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody id="products">
</tbody>
</table>
<hr />
Id:
<asp:TextBox runat="server" ID="txtId">10</asp:TextBox>
Name:
<asp:TextBox runat="server" ID="txtName">Test</asp:TextBox>
Category:
<asp:TextBox runat="server" ID="txtCategory">Test Category</asp:TextBox>
Price:
<asp:TextBox runat="server" ID="txtPrice">5.50</asp:TextBox>
</div>
<p>
<input id="btn" type="button" value="POST" />
</p>
</form>
</body>
</html>+++++++++++++++++++++++++++++++++++++++++++++ ProductsController.cs ++++++++++++++++++++++++++++
namespace WebForms
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
};
public IEnumerable<Product> GetAllProducts()
{
return products;
}
public Product GetProductById(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return product;
}
public IEnumerable<Product> GetProductsByCategory(string category)
{
return products.Where(
(p) => string.Equals(p.Category, category,
StringComparison.OrdinalIgnoreCase));
}
public string AppendRow([FromBody] YourObjectDto prodDTO)
{
var id = prodDTO.Id;
var name = prodDTO.Name;
var category = prodDTO.Category;
var price = prodDTO.Price;
//new Product { Id = id, Name = name, Category = category, Price = price };
return "success";
}
// POST api/Products
public Product Post([FromBody]Product prodDTO)
{
return prodDTO;
}
}
}Friday, December 29, 2017 3:33 AM