Editing content directly within an ASP.NET Core MVC application through AJAX encounters a 400 error, indicating a Bad Request

I'm attempting to implement inline editing using AJAX in ASP.NET Core MVC, but I keep receiving a 400 error (Bad Request).

The idea is to click on a table row to edit and save the new values in an SQL database.

Could someone confirm if I am on the right track or point out any mistakes? Additionally, are there better approaches to accomplish this?

Here's my Index.cshtml:

@model IEnumerable<officeprotocol.Areas.UpdatedThankReq.Models.MainTexts>

<table class="table" id="tstTable">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Id)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.BeginText)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.EndText)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td class="maintxtId">
                    <span id="idVal">@item.Id</span>
                </td>
                <td class="maintxtBegin">
                    <span>@item.BeginText</span>
                    <input id="bgnTxtIn" type="text" value="@item.BeginText" style="display:none"/>
                </td>
                <td class="maintxtEnd">
                    <span>@item.EndText</span>
                    <input id="endTxtIn" type="text" value="@item.EndText" style="display:none" />
                </td>
                <td>
                    <a class="Edit" href="javascript:;">Edit</a>
                    <a class="Update" href="javascript:;" style="display:none">Update</a>
                    <a class="Cancel" href="javascript:;" style="display:none">Cancel</a>
                    <a class="Delete" href="javascript:;">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

@section scripts 
{
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/jquery/dist/jquery.js"></script>

    <script type="text/javascript">
    $(document).ready(function () {
        $("body").on("click", '#tstTable .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();
        });

        $("body").on("click", '#tstTable .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 MaintxtViewModel = {
                                        Id: parseInt($("#idVal").html()),
                                        BeginText: $("#bgnTxtIn").val(),
                                        EndText: $("#endTxtIn").val()

                                    };

            $.ajax ({
                  type: 'POST',
                  url: "/ReqArea/MainTexts/Edit",
                  data: { mainTexts: MaintxtViewModel },

                  success: function (result) {
                      alert("Saved");
                  },
                  failure: function (result) {
                      alert("Failed")
                  },
                  error: function (result) {
                      alert("SaveError");
                  }
              });
          });
      });
    </script>
}

My Controller in area

    public async Task<IActionResult> Edit(int? id)
    {
        if (id == null || _context.MainTexts == null)
        {
            return NotFound();
        }

        var mainTexts = await _context.MainTexts.FindAsync(id);

        if (mainTexts == null)
        {
            return NotFound();
        }

        return View(mainTexts);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(int id, [Bind("Id,BeginText,EndText")] MainTexts mainTexts)
    {
        if (id != mainTexts.Id)
        {
            return NotFound();
        }

        if (ModelState.IsValid)
        {
            try
            {
                _context.Update(mainTexts);
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!MainTextsExists(mainTexts.Id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
            return RedirectToAction(nameof(Index));
        }
        return View(mainTexts);
}

https://i.stack.imgur.com/ACei8.png

I've been troubleshooting this issue multiple times without success.

All I need now is for the action to execute properly.

Answer №1

By removing the [ValidateAntiForgeryToken] attribute, you can resolve your current issue.

Additionally, here are some other issues to address:

1. Make sure to pass the id in the route:

url: "/ReqArea/MainTexts/Edit/" + parseInt($("#idVal").html()),

2. The code you used to retrieve input values will always target the first tr. You need to modify your JavaScript code as follows:

var MaintxtViewModel = {
        Id: parseInt($(this).closest('tr').find('td span#idVal').html()),
        BeginText: $(this).closest('tr').find('td input#bgnTxtIn').val(),
        EndText: $(this).closest('tr').find('td input#endTxtIn').val()
                        };

3. The value attribute always reflects the original value, so add the following JavaScript code:

var defaultBgnTxtInValue = $("#bgnTxtIn").val();
var defaultEndTxtInValue = $("#endTxtIn").val();
    $("table input[type='text']").on("change", function () {
        // Get the parent <td> and <tr> elements of the changed input
        var tdElement = $(this).closest("td");
        var trElement = $(this).closest("tr");

        // Get the ID of the changed input element
        var changedInputId = $(this).attr("id");
        var newValue = $(this).val();
        if (changedInputId == "bgnTxtIn") {
            if (newValue !== defaultBgnTxtInValue) {
                // Update the default value with the new value
                $(this).attr('value', newValue);
            }
        }
        else {
            if (newValue !== defaultEndTxtInValue) {
                // Update the default value with the new value
                $(this).attr('value', newValue);
            }
        }
    });
$("body").on("click", '#tstTable .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();        
});

The complete JavaScript code

@section scripts 
{
    <script type="text/javascript">
    $(document).ready(function () {
        var defaultBgnTxtInValue = $("#bgnTxtIn").val();
        var defaultEndTxtInValue = $("#endTxtIn").val();
            $("table input[type='text']").on("change", function () {
                // Get the parent <td> and <tr> elements of the changed input
                var tdElement = $(this).closest("td");
                var trElement = $(this).closest("tr");

                // Get the ID of the changed input element
                var changedInputId = $(this).attr("id");
                var newValue = $(this).val();
                if (changedInputId == "bgnTxtIn") {
                    if (newValue !== defaultBgnTxtInValue) {
                        // Update the default value with the new value
                        $(this).attr('value', newValue);
                    }
                }
                else {
                    if (newValue !== defaultEndTxtInValue) {
                        // Update the default value with the new value
                        $(this).attr('value', newValue);
                    }
                }
            });
        $("body").on("click", '#tstTable .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();
                
        });
           
        $("body").on("click", '#tstTable .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 MaintxtViewModel = {
        Id: parseInt($(this).closest('tr').find('td span#idVal').html()),
        BeginText: $(this).closest('tr').find('td input#bgnTxtIn').val(),
        EndText: $(this).closest('tr').find('td input#endTxtIn').val()

                            // Id: parseInt(row.find(".maintxtId").find("span").html()),
                            // BeginText: row.find(".maintxtBegin").find("span").html(),
                            // EndText: row.find(".maintxtEnd").find("span").html()
                        };

            $.ajax ({
                  type: 'POST',
                    url: "/ReqArea/MainTexts/Edit/" + parseInt($(this).closest('tr').find('td span#idVal').html()),
                  data: { mainTexts: MaintxtViewModel },

                  success: function (result) {
                      alert("Saved");
                  },
                  failure: function (result) {
                      alert("Failed")
                  },
                  error: function (result) {
                      alert("SaveError");
                  }
              });
          });
      });
    </script>
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Troubleshooting the malfunction of jQuery's change() function

There are three HTML select tags on my page. I want these three select tags to function as follows: When I change selectA, selectB should automatically update based on the selection in selectA. Similarly, when an option in selectB is created, changing se ...

Text Parallax Effect

For my website, I am interested in incorporating a unique parallax effect. Instead of just fixing a background image and allowing scrolling over it, I want to apply this effect to all of the content on my site. The website consists of a single page with m ...

Retrieving information from PHP using AJAX

As a newcomer to the world of AJAX, I am faced with the task of retrieving data from a PHP file and storing it in a JavaScript variable. Despite exploring several examples, I have not been able to find a satisfactory solution. Here is a simplified HTML cod ...

What is the best way to send JSON data from Express to a JavaScript/jQuery script within a Pug template?

Currently, I am facing a challenge in passing JSON data from an Express route to a .js file located within a .pug template. I have been attempting to solve this issue using the following method: The router: // Office Locations router.get('/office_lo ...

How to Retrieve the Absolute Index of the Parent Column Using jQuery Datatables

I recently developed a custom column filtering plugin for datatables, but I've encountered a minor issue. Within each column footer, I have added text inputs, and now I am trying to capture their indexes on keyup event to use them for filtering. In ...

I am trying to dynamically load a div using Ajax, but whenever I do so, the position of the div changes. Is

I'm currently experiencing an issue with the function I'm using to refresh a section of my webpage. It seems that the ul#bla is being loaded twice, causing the list to shift position to the right. Is there a way for me to use this function to re ...

What is the best jQuery event or method to use for attaching functionality to a dynamic button before it is clicked?

My goal is to connect a jQuery plugin to a button that is dynamically generated. I have attempted the following without success: $('.myButton').on('click', function() { $(this).file().choose(function(e, input) { // ... ...

Utilizing Spring MVC for efficient AJAX requests

I'm facing an issue while trying to convert a JSON object to a Java object in my controller using AJAX. I am currently using Jackson 2.2.3 and Spring 4.0.0. Can someone please help me identify where I might have gone wrong? Thank you. Here is a snipp ...

How to Use Radio Buttons in Material-UI to Disable React Components

Just starting out with ReactJS and Material-UI, I've been experimenting with them for about 3 weeks. Currently, I'm facing a challenge where: - There are 2 radio buttons in a group and 2 components (a text field and a select field); - The goal is ...

jQuery fadeIn effect happening at rapid speed

I am currently working on integrating ajax with WordPress. After the ajax call is completed, I am successfully fading out a specific div slowly. However, when trying to fade in the new data using jQuery's fadeIn() method, I noticed that regardless of ...

Mastering the Art of Live Search in Drop Down Multi Select

I need to develop a search functionality similar to the one found on . This search should allow users to select options from a dropdown menu or type their own search query, and provide live search results. I attempted to use the jQuery plugin https://www.j ...

Tips for choosing the dropdown selection on an ASPX website page

I have a specific dropdown menu set up, and I need to select the appropriate option from the viewdata object in my .aspx page. Here is what my menu looks like: <td headers="Vehicle" style="background-color:#EFF3FB;font-family: Verdana; font-size: 10px ...

Utilize a Vue.js filter on the v-model within an input element

Seeking assistance! I successfully created a directive that wraps the Jasny Bootstrap Plugin, specifically focusing on the input mask feature! Additionally, I have developed a custom filter using moment to format date fields! The date format received fro ...

Dynamically insert <td> elements into <tr> element using both jQuery and JavaScript

I am facing an issue with adding a new table data (td) element dynamically to the first table row (tr) in my JavaScript code. Here is the original table before adding the new td element: <table> <tbody> <tr> <t ...

parsing links from HTML tag

I am trying to extract the img src tag from an HTML request that includes the following element: <img src="https://pbs.twimg.com/media/...." alt="Embedded image permalink"</a> My goal is to retrieve only the URL. Currently, I might be going too ...

Encountering 'Error 405 - Method not Supported' while making an Ajax POST request in ASP.NET Web API

I am currently in the process of developing a straightforward Web API service that captures input data from an HTML form, converts it into JSON format, and forwards it to a Web API. My coding platform is ASP.NET Web API on Visual Studio 2017. To further el ...

The Ajax response fails to update my viewmodel

I have a value and a list that I need to update from within an Ajax callback. After retrieving a fresh value using .get(), I try to assign it to my view model's property, but the UI does not refresh properly. Below is the code snippet: function Searc ...

The accordion won't function properly if it is added using append() after the document is ready

I have implemented a button to add an accordion, but unfortunately it doesn't seem to be working properly. I am unsure of how to troubleshoot and resolve this issue. If the accordion HTML is appended after the document.ready() function, then the accor ...

Checking the status: Real-time validation of checkboxes using jQuery

I am currently utilizing the jQuery validation plugin known as jQuery validation. In my code snippet below, I have a straightforward validation method that checks the number of checkboxes that are selected based on a specified parameter: $.validator.metho ...

All you need to know about the jQuery .css method

I've been struggling to get this script to function properly. Despite searching online, I haven't been able to find a satisfactory solution. $( document ).ready(function() { $("#container").click(function(){ var color = $(this).css("backgro ...