Search code examples
javascripthtml.netmodel-view-controller

CRUD Update in .net Core and cshtml


I apologize in advance if this is a simple question, I am studying .net and I really want to be able to make an Update function I have created a .net 6 MVC solution

I created a CardsController:

    public class CardsController : Controller {

        private readonly CardsContext _context;
        public CardsController(CardsContext context) {
            _context = context;
        }

        public IActionResult Index() {
            var cards = _context.Cards.ToList();
            return View(cards);
        }

        [HttpGet]
        public IActionResult Create() {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create([Bind("Title,Description,Stage,Tag")] CardsModel cardsModel) {
            if (ModelState.IsValid) {
                _context.Add(cardsModel);
                _context.SaveChanges();
                return RedirectToAction(nameof(Index));
            }
            return View(cardsModel);
        }

        [HttpGet]
        public IActionResult Update(int? id) {
            if (id == null) {
                return NotFound();
            }

            var cardsModel = _context.Cards.Find(id);
            if (cardsModel == null) {
                return NotFound();
            }

            return View(cardsModel);
        }

        [HttpPut]
        [ValidateAntiForgeryToken]
        public IActionResult Update(int id, [FromBody] CardsModel cardsModel) {

            if(id != cardsModel.id) {
                return NotFound();
            }

            if (ModelState.IsValid) {
                try {
                    _context.Update(cardsModel);
                    _context.SaveChanges();
                }
                catch (DbUpdateConcurrencyException) {
                    return NotFound();
                }
                return RedirectToAction(nameof(Index));
            }

            return View(cardsModel);

        }

        [HttpDelete]
        public ActionResult Delete(int? id)
        {
            
            if (id == null){
                return NotFound();
            }

            var cardsModel = _context.Cards.Find(id);

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

            _context.Cards.Remove(cardsModel);
            _context.SaveChanges();
            return RedirectToAction(nameof(Index));

        }


    }

I created a route for my actions:

app.UseEndpoints(endpoints => {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Cards}/{action=Index}/{id?}");
                endpoints.MapControllerRoute(
                    name: "Delete",
                    pattern: "Cards/Delete/{id?}",
                    defaults: new { controller = "Cards", action = "Delete" });
                endpoints.MapControllerRoute(
                    name: "Update",
                    pattern: "Cards/Update/{id?}",
                    defaults: new { controller = "Cards", action = "Update" });
            });

I created a function in cshtml for the Delete and Update:

<script>
    function deleteCard(id) {
        fetch('/Cards/Delete/' + id, {
            method: 'Delete'
        })
            .then(response => {
                if (response.ok) {
                    alert('Success!');
                } else {
                    alert('Error.');
                }
            })
            .catch(error => {
                alert('Error.');
                console.error(error);
            });
    }

    function UpdateCard(id) {
        fetch(`/Cards/Update/${id}`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                id: id,
                Title: "UpdatedCard",
                Description: "UpdatedCard",
                Stage: 0,
                Tag: 0
            })
        })
            .then(response => {
                if (response.ok) {
                    // atualização bem-sucedida, redirecionar para a página inicial
                    window.location.href = '/Cards/Index';
                } else {
                    // atualização falhou, lidar com o erro
                    console.error('Error updating card.');
                }
            })
            .catch(error => {
                console.error(error);
            });
    }



</script>

And when I call the UpdateCard function in the cshtml I get two errors in the console: PUT https://localhost:44307/Cards/Update/9 net::ERR_ABORTED 400 Error updating card.

Note: The Delete Function works Can you look at my simple code and point out where the error might be?


Solution

  • Since you are applying the ValidateAntiForgeryToken to the Update action, you would need to include the antiforgery token in the request as shown in the docs. As you are building an API, it is recommended to protect the endpoints using authorization instead, see e.g. this question for details about that.