1

Please can you help me to work out why I can't seem to pass in the data using the data parameter, and have to use the URL.

I'm a relatively new developer here, so perhaps this is more of a failure on my part to know what to Google - but I'm pretty sure the below is not a good way of getting data into my database via Web API. This is an example from asp.NET that I tried to modify, with limited success. Using either of the other two approaches doesn't reach my Controller class.

Any thoughts on why the two commented sections below don't work would be greatly appreciated.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Product App</title>
    <meta charset="utf-8"/>
</head>
<body>
    <div>
        <h2>All Products</h2>
        <ul id="products"/>
    </div>
    <div>
        <h2>Search by ID</h2>
        <input type="text" id="prodId" size="5" />
        <input type="button" value="Search" onclick="find();" />
        <p id="product"/>
    </div>
    <div>
        <h2>Add Product</h2>
        <form>
            ID:<br>
            <input type="number" id="setProdId" size="5"/><br>
            Name:<br>
            <input type="text" id="setProdName" size="10"/><br>
            Category:<br>
            <input type="text" id="setProdCategory" size="10"/><br>
            Price:<br>
            <input type="number" id="setProdPrice" size="10"/><br><br>
            <input type="button" value="Add" onclick="create();"/>
            <p id="setProduct"/>
        </form>
    </div>

    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
    <script>
    var uri = 'api/products';

    $(document).ready(function () {
      // Send an AJAX request
      $.getJSON(uri)
          .done(function (data) {
            // On success, 'data' contains a list of products.
            $.each(data, function (key, item) {
              // Add a list item for the product.
              $('<li>', { text: formatItem(item) }).appendTo($('#products'));
            });
          });
    });
    function formatItem(item)
    {
      return item.Name + ': $' + item.Price;
    }

    function find()
    {
      var id = $('#prodId').val();
      $.getJSON(uri + '/' + id)
          .done(function (data) {
            $('#product').text(formatItem(data));
          })
          .fail(function (jqXHR, textStatus, err) {
            $('#product').text('Error: ' + err);
          });
    }



    function create() {

        var settings = {
            "url": uri + "?id=" + $('#setProdId').val() + "&name=" + $('#setProdName').val() + "&category=" + $('#setProdCategory').val() + "&Price=" + $('#setProdPrice').val() + "",
            "method": "POST",
        }

        $.ajax(settings).done(function (response) {
            console.log(response)
        });

        //  $.ajax({
        //    method: "POST",
        //    url: uri,
        //    data: { id: $('#setProdId').val(), name: $('#setProdName').val(), category: $('#setProdCategory').val(), price: $('#setProdPrice').val() },
        //    contentType: "application/json",
        //    dataType: 'json'
        //});

        //    $.post(uri,
        //        {
        //            $('#setProdId').val(),
        //            $('#setProdName').val(),
        //            $('#setProdCategory').val(),
        //            $('#setProdPrice').val()
        //        }
        //    );
        //};
    }

   </script>
</body>
</html>

Below is the Controller:

using ProductsApp.Models;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;{

        bool isSuccess = false;
        string connectionString = "my connection string";


        public int RetrieveProductsCount()
        {
            int count = 0;

            string strCount = "";

            using (SqlConnection myConnection = new SqlConnection())
            {
                myConnection.ConnectionString = connectionString;
                string oString = "SELECT COUNT(ID) as Count FROM tblProduct";
                myConnection.Open();
                SqlCommand oCmd = new SqlCommand(oString, myConnection);

                using (SqlDataReader oReader = oCmd.ExecuteReader())
                {
                    while (oReader.Read())
                    {
                        strCount = oReader["Count"].ToString();
                    }

                    try
                    {

                        isSuccess = int.TryParse(strCount, out count);
                        Console.WriteLine("Count of Products: " + count);

                    }
                    catch (System.FormatException e)
                    {
                        Console.WriteLine(e.Message);
                    }

                }
                myConnection.Close();
            }

            return count;

        }

        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()
        {
            string sqlCommand = "SELECT * FROM tblProduct";
            DataSet ds = new DataSet();
            List<Product> productList;

            using (SqlCommand cmd = new SqlCommand(sqlCommand, new SqlConnection(connectionString)))
            {
                cmd.Connection.Open();
                DataTable table = new DataTable();
                table.Load(cmd.ExecuteReader());
                ds.Tables.Add(table);

                productList = new List<Product>();
                for (int i = 0; i < table.Rows.Count; i++)
                {
                    Product product = new Product();
                    product.Id = Convert.ToInt32(table.Rows[i]["ID"]);
                    product.Name = table.Rows[i]["Name"].ToString();
                    product.Category = table.Rows[i]["Category"].ToString();
                    product.Price = Convert.ToDecimal(table.Rows[i]["Price"]);
                    productList.Add(product);
                }

                cmd.Connection.Close();
            }

            products = productList.ToArray();

            return products;
        }

        public IHttpActionResult GetProduct(int id)

        {

            string sqlCommand = "SELECT TOP(1) * FROM tblProduct WHERE ID =" + id.ToString();
            DataSet ds = new DataSet();
            Product lProduct = new Product();

            using (SqlCommand cmd = new SqlCommand(sqlCommand, new SqlConnection(connectionString)))
            {
                cmd.Connection.Open();
                DataTable table = new DataTable();
                table.Load(cmd.ExecuteReader());
                ds.Tables.Add(table);

                if (table.Rows.Count > 0)
                {
                    lProduct.Id = Convert.ToInt32(table.Rows[0]["ID"]);
                    lProduct.Name = table.Rows[0]["Name"].ToString();
                    lProduct.Category = table.Rows[0]["Category"].ToString();
                    lProduct.Price = Convert.ToDecimal(table.Rows[0]["Price"]);
                }

                else lProduct = null;

                cmd.Connection.Close();

            }

            //var product = products.FirstOrDefault((p) => p.Id == id);
            if (lProduct == null)
            {

                return NotFound();

            }

            return Ok(lProduct);


        }

        [HttpPost]
        public IHttpActionResult Create(int id, string name, string category, decimal price)
        {

            string sqlCommand = "INSERT INTO tblProduct (Id, Name, Category, Price) VALUES (@id, @name, @category, @price)";

            using (SqlCommand cmd = new SqlCommand(sqlCommand, new SqlConnection(connectionString)))
            {
                cmd.Connection.Open();

                cmd.Parameters.AddWithValue("@id", id);
                cmd.Parameters.AddWithValue("@name", name);
                cmd.Parameters.AddWithValue("@category", category);
                cmd.Parameters.AddWithValue("@price", price);
                try
                {
                    cmd.ExecuteNonQuery();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);

                }
                cmd.Connection.Close();

            }

            return Ok();
        }

    }
}
using System.Web.Http;

namespace ProductsApp.Controllers
{
    public class ProductsController : ApiController
3
  • Your $.ajax call looks fine to me, so it may be an issue server-side that isn't reading the request body and only reads query string params. Commented Aug 15, 2016 at 18:19
  • Show us your controller action. Commented Aug 15, 2016 at 18:30
  • Many thanks for your response, I've added the Controller class to the original post above. Commented Aug 15, 2016 at 18:47

1 Answer 1

2

Your Controller expect Post method

[HttpPost]
public IHttpActionResult Create(int id, string name, string category, decimal price)

But you sent GET request, because $.getJson load JSON-encoded data from the server using a GET HTTP request.

Just use your $.ajax request as you commented but with correct method inside Controller.

Another point I found you define verb only for controller Create, but uri requested product. To fix that use in case of MVC:

 $.ajax({
            url: "@Url.Action("Create", "api")",
            method: "POST",
            ... //Rest of your code

And last point if you need JSON just return JsonResult from controller again in case MVC.

[HttpPost]
public JsonResult Create(int id, string name, string category, decimal price)
{
   //your code
    return Json(new { total = products.Count, records = products}, JsonRequestBehavior.AllowGet);
}

UPDATE

I will explain.

var uri = 'api/products';

$(document).ready(function () {
  // Send an AJAX request
  $.getJSON(uri)
      .done(function (data) {
        // On success, 'data' contains a list of products.
        $.each(data, function (key, item) {
          // Add a list item for the product.
          $('<li>', { text: formatItem(item) }).appendTo($('#products'));
        });
      });
});

This part: requires GET verb to action products but you don't have this action within controller.

This part:

function find()
{
  var id = $('#prodId').val();
  $.getJSON(uri + '/' + id)
      .done(function (data) {
        $('#product').text(formatItem(data));
      })
      .fail(function (jqXHR, textStatus, err) {
        $('#product').text('Error: ' + err);
      });
}

uses again wrong action but almost correct syntax.

 $.getJSON('Api/GetProduct', {id: id})

This should work.

p.s. My first point in the earlier response maybe was not clear in the case of required verb. I was confused because you defined only one uri but use it in the different places with access to different actions

Sign up to request clarification or add additional context in comments.

2 Comments

Many thanks for your answer, much appreciated. Would you mind clarifying a couple points for me: "Just use your $.ajax request as you commented but with correct method inside Controller." - I'm not sure I understand what the correct method would be in this case. Also, this line: url: "@Url.Action("Create", "api")" doesn't seem to parse in VS 2015, it seems to break out of the string. Any help with these gratefully appreciated.
var uri = 'api/products'; means Controller/Action. I didn't find action calls products. Line @Url.Action doesn't have proper behavior for MVC5 in VS 2015 with latest update. It's known issue

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.