Home > Net >  ActionResult is never invoked in ASP.NET MVC / C#
ActionResult is never invoked in ASP.NET MVC / C#

Time:11-11

I need to update the price of a particular product in my ASP.NET MVC application connected to a local database.

The ProductController is the following, which should update the content of the database:

[HttpPost]
public ActionResult UpdatePrice(Models.Product product)
{
    string query = "UPDATE product SET price=@price  WHERE productId=@idproduct";
      
    string constr = "server=localhost;user id=root;password=;database=accounting;persistsecurityinfo=True";

    using(MySqlConnection con = new MySqlConnection(constr))
    {
        using (MySqlCommand cmd = new MySqlCommand(query))
        {
            cmd.Parameters.AddWithValue("@idproduct", product.idproduct);
            cmd.Parameters.AddWithValue("@price", product.price);
            cmd.Parameters.AddWithValue("@name", product.name);
            cmd.Parameters.AddWithValue("@description", product.description);
            cmd.Parameters.AddWithValue("@cost", product.cost);
            cmd.Parameters.AddWithValue("@quantity", product.quantity);
            cmd.Parameters.AddWithValue("@sku", product.sku);

            cmd.Connection = con;

            con.Open();
            cmd.ExecuteNonQuery();

            Console.WriteLine(product.price);
            con.Close();
        }
    }

    return new EmptyResult();
}

This is the view of the product, that in the same file shows all the products and allow a user to edit the price of the product by using Javascript

<table class="table" id="tblProducts">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.description)
        </th>
       
        <th>
            @Html.DisplayNameFor(model => model.price)
        </th>
       
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td class="Product Name">
                <span>@item.name</span>
                
            </td>
            <td class="Description">
                <span>@item.description</span>
               
            </td>
            <td class="Price">
                <span>@item.price</span>
                <input type="text" value="@item.price" style="display:none; width: 50px;" />
            </td>

            <td>
                <a class="Edit" href="javascript:;"  " >Edit</a>
                <a hljs-string">" href="javascript:;"  "style="display:none">Update</a>
                <a class="Cancel" href="javascript:;" style="display:none">Cancel</a>
                
            </td>
        </tr>

    }
</table>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script type="text/javascript" src="https://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
    <script type="text/javascript">
        //Edit event handler.
        $("body").on("click", "#tblProducts .Edit", function () {
            var row = $(this).closest("tr");
            $("td", row).each(function () {
                if ($(this).find("input").length > 0) {
                    $(this).find("input").show();
                    $(this).find("span").hide();
                }
            });
            row.find(".Update").show();
            row.find(".Cancel").show();
            row.find(".Delete").hide();
            $(this).hide();
        });
        //Update event handler.
        $("body").on("click", "#tblProducts .Update", function () {
            var row = $(this).closest("tr");
            $("td", row).each(function () {
                if ($(this).find("input").length > 0) {
                    var span = $(this).find("span");
                    var input = $(this).find("input");
                    span.html(input.val());
                    span.show();
                    input.hide();
                }
            });
            row.find(".Edit").show();
            row.find(".Delete").show();
            row.find(".Cancel").hide();
            $(this).hide();

            var product = {};
            //product.idproduct= row.find(".productId").find("span").html();
            //product.name = row.find(".Product Name").find("span").html();
            product.price = row.find(".Price").find("span").html();
            $.ajax({
                type: "POST",
                url: "/Product/UpdatePrice",
                data: '{product:'   JSON.stringify(product)   '}',
                contentType: "application/json; charset=utf-8",
                dataType: "json"
            });
        });
 </script>

The problem I am having is that the price is updated in the html page, and I can see the changes, but no changes are actually applied to the database, looking at it I can only see updates if I actually update manually the database from MySql Workbench. Any suggestion on what I should do? I have put breakpoints in Visual Studio and it seems that the price is changed in the Product model, but nothing is updated in the database.

CodePudding user response:

In your view, put the product id into a hidden input, so you can pass it to the controller when you post:

...

@foreach (var item in Model)
{
    <tr>
        <td class="Product Name">
            <span>@item.name</span>               
        </td>
        <td class="Description">
            <span>@item.description</span>               
        </td>
        <td class="Price">
            <span>@item.price</span>
            <input type="text" value="@item.price" style="display:none; width: 50px;" />
        </td>

        <td>
            @*Adding a hidden input with the product id on next line*@
            <input type="hidden" value="@item.idproduct" style="display:none;" class="hdn-product-id" />
            <a class="Edit" href="javascript:;"  " >Edit</a>
            <a hljs-string">" href="javascript:;"  "style="display:none">Update</a>
            <a class="Cancel" href="javascript:;" style="display:none">Cancel</a>                
        </td>
    </tr>
}

Now you can grab the product's id when the update button is pressed, I also added success and error callbacks for your Ajax:

    //Update event handler.
    $("body").on("click", "#tblProducts .Update", function () {
        const row = $(this).closest("tr");
        //now we can get the product id to pass to the controller
        const prodid = $(this).closest('td').find('.hdn-product-id').val();
        
        $("td", row).each(function () {
            if ($(this).find("input").length > 0) {
                var span = $(this).find("span");
                var input = $(this).find("input");
                span.html(input.val());
                span.show();
                input.hide();
            }
        });
        row.find(".Edit").show();
        row.find(".Delete").show();
        row.find(".Cancel").hide();
        $(this).hide();

        var product = {};
        
        product.price = row.find(".Price").find("span").html();
        //set the id to the model
        product.idproduct = prodid;
         
        $.ajax({
            type: "POST",
            url: "/Product/UpdatePrice",
            data: '{product:'   JSON.stringify(product)   '}',
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(data){
                //do something on success of post
            },
            error: function(jqXHR, exception){
               //do something on error
            }
        });
    });

Now when your Post method occurs, you should have the id of the product to update and your query will behave as expected.

  • Related