Lesson Wednesday

In the last lesson we discussed CRUD actions and their corresponding HTTP request methods. So far, our to do list can create Items with a POST request via our form and read Items with a GET request so users can see the full to do list.

Let's add functionality to delete Items. Then we'll walk through updating Items in later lessons.

Clearing Item Lists


We'll begin by adding functionality to delete all Items, as this broader action should be simpler to begin with.

HTML Form

First, we need a button users can click to invoke this action. We'll add one to the bottom of our Items/Index.cshtml view:

ToDoList/Views/Items/Index.cshtml
...

<form action="/items/delete" method="post">
  <button type="submit" name="button">Clear All Items</button>
</form>

The entire updated file looks like this:

ToDoList/Views/Items/Index.cshtml
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My To-Do List!</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
  </head>
  <body>
    @using ToDoList.Models;

    <h1>To Do List</h1>
    @if (Model.Count == 0)
    {
      <p>There are no items in the list.</p>
    }
    <ul>
      @foreach (Item item in Model)
      {
        <li>@item.Description</li>
      }
    </ul>

    <a href="/items/new">Add a new item.</a>

    <form action="/items/delete" method="post">
      <button type="submit" name="button">Clear All Items</button>
    </form>
  </body>
</html>

Notice this button resides in <form> tags. It's not a standalone <button> element. Only forms can submit and use the POST method required to update the server. Deleting something is still considered a server update because data is changing. A few more things to notice:

  • The action attribute is "/items/delete". The route that will run when the button is clicked must have this same path.

  • The method attribute is post. This will create a POST request to update the server. The corresponding route path must be defined with HttpPost().

  • We also add type="submit" to the button. This is always required to successfully send a POST request from a form, even if that form is just a button.

Corresponding POST Route

Let’s create the route that will handle this form's submission. We'll add the following to ItemsController.cs below our Create() route:

ToDoList/Controllers/ItemsController.cs
...

    [HttpPost("/items/delete")]
    public ActionResult DeleteAll()
    {
      Item.ClearAll();
      return View();
    }

...
  • Notice the "/items/delete" path matches the action attribute of the form exactly.

  • We also use HttpPost() to denote this route will handle POST requests, since our form's method is set to "post".

  • Because the route's path and HTTP method match the form's path and action attribute, this route will be invoked when our form is submitted.

  • Once invoked by a POST request to "/items/delete" (which will happen when our new form is submitted), the route calls the static ClearAll() method, which we already defined in our Item.cs model.

The entire updated controller file looks like this:

ToDoList/Controllers/ItemsController.cs
using Microsoft.AspNetCore.Mvc;
using ToDoList.Models;
using System.Collections.Generic;

namespace ToDoList.Controllers
{
  public class ItemsController : Controller
  {
    [HttpGet("/items")]
    public ActionResult Index()
    {
      List<Item> allItems = Item.GetAll();
      return View(allItems);
    }

    [HttpGet("/items/new")]
    public ActionResult CreateForm()
    {
      return View();
    }

    [HttpPost("/items")]
    public ActionResult Create(string description)
    {
      Item myItem = new Item(description);
      return RedirectToAction("Index");
    }

    [HttpPost("/items/delete")]
    public ActionResult DeleteAll()
    {
      Item.ClearAll();
      return View();
    }
  }
}

Success Page

Because our new DeleteAll() route returns View(), it will automatically look for a view file matching the route name. The route is named DeleteAll() and exists on the ItemsController, so we'll need a DeleteAll.cshtml file in Views/Items. Let's create this now:

ToDoList/Views/Items/DeleteAll.cshtml
<h1>Your list has been cleared!</h1>
<p><a href="/items">Back to list.</a></p>

This will display a success message confirming Items were deleted and include a link back to the /items page. If we wanted, we could also choose to use a redirect to go back to the index or home page as well.

Repository Reference

Follow the link below to view how a sample version of the project should look at this point. Note that this is a link to a specific commit in the repository.

Example GitHub Repo for To Do List

Adding Delete to a Form Example

...

<form action="/items/delete" method="post">
  <button type="submit" name="button">Clear All Items</button>
</form>

Adding Delete to a Controller Example

[HttpPost("/items/delete")]
public ActionResult DeleteAll()
{
  // Code goes here.
}

Lesson 30 of 38
Last updated more than 3 months ago.