Lesson Wednesday

Now let's make sure our application can also destroy a task. We'll add a Delete link on the item's detail page. Clicking this link will take the user to a page that confirms they'd like to delete this particular task.

Updating the Controller


Once again, let's start with the necessary controller actions:

ItemsController.cs
...
public ActionResult Delete(int id)
{
    var thisItem = _db.Items.FirstOrDefault(item => item.ItemId == id);
    return View(thisItem);
}

[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
    var thisItem = _db.Items.FirstOrDefault(item => item.ItemId == id);
    _db.Items.Remove(thisItem);
    _db.SaveChanges();
    return RedirectToAction("Index");
}
...

Here, our POST action is named DeleteConfirmed instead of Delete. This is because both the GET and POST action methods for Delete take id as a parameter. However, C# will not allow us to have two methods with the same signature. Remember that the signature is the method name and parameters. The POST attribute is not considered part of the method signature so the C# compiler will think the actions above are the same method if we name them both Delete.

To avoid errors, we call one of our methods Delete and the other DeleteConfirmed. Note that our annotation includes [ActionName("Delete")]. This is so we can still utilize the proper Delete action even though we've named our method DeleteConfirmed.

Other than that, the code is very similar to what we've seen so far. The Delete() action looks just like our GET actions Create() and Edit(): we simply need to get the correct item and return it to the view.

The DeleteConfirmed() method is also very similar to the code we've used in other actions. The only difference is that we utilize the built-in Remove() method on _db.Items.

Updating the View


Now let's create the corresponding view:

Views/Items/Delete.cshtml
@{
  Layout = "_Layout";
}

@model ToDoList.Models.Item

<h2>Are you sure you want to delete this?</h2>

@Html.DisplayNameFor(model => model.Description): @Html.DisplayFor(model => model.Description)
@using (Html.BeginForm())
{
    <input type="submit" value="Delete" />
}
@Html.ActionLink("Back to List", "Index")

By default, the HTML helper method BeginForm() creates a POST request to an action method whose name matches the .cshtml file it's contained in. That means the BeginForm() helper seen in our Delete.cshtml file above will automatically create a POST request to our Delete action. This is why our annotation includes ActionName("Delete").

Let's also add a delete link to details.cshtml:

<p>@Html.ActionLink("Delete Item", "Delete", new { id = Model.ItemId })</p>

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

Controllers/ItemsController.cs

using Microsoft.AspNetCore.Mvc;
using ToDoList.Models;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;

namespace ToDoList.Controllers
{
  public class ItemsController : Controller
  {
    private readonly ToDoListContext _db;

    public ItemsController(ToDoListContext db)
    {
      _db = db;
    }

    public ActionResult Index()
    {
      List<Item> model = _db.Items.ToList();
      return View(model);
    }

    public ActionResult Create()
    {
      return View();
    }

    [HttpPost]
    public ActionResult Create(Item item)
    {
      _db.Items.Add(item);
      _db.SaveChanges();
      return RedirectToAction("Index");
    }

    public ActionResult Details(int id)
    {
      Item thisItem = _db.Items.FirstOrDefault(item => item.ItemId == id);
      return View(thisItem);
    }

    public ActionResult Edit(int id)
    {
      var thisItem = _db.Items.FirstOrDefault(item => item.ItemId == id);
      return View(thisItem);
    }

    [HttpPost]
    public ActionResult Edit(Item item)
    {
      _db.Entry(item).State = EntityState.Modified;
      _db.SaveChanges();
      return RedirectToAction("Index");
    }

    public ActionResult Delete(int id)
    {
      var thisItem = _db.Items.FirstOrDefault(item => item.ItemId == id);
      return View(thisItem);
    }

    [HttpPost, ActionName("Delete")]
    public ActionResult DeleteConfirmed(int id)
    {
      var thisItem = _db.Items.FirstOrDefault(item => item.ItemId == id);
      _db.Items.Remove(thisItem);
      _db.SaveChanges();
      return RedirectToAction("Index");
    }
  }
}

Views/Items/Delete.cshtml

@{
  Layout = "_Layout";
}

@model ToDoList.Models.Item

<h2>Are you sure you want to delete this?</h2>

@Html.DisplayNameFor(model => model.Description): @Html.DisplayFor(model => model.Description)
@using (Html.BeginForm())
{
    <input type="submit" value="Delete" />
}
@Html.ActionLink("Back to List", "Index")

Lesson 32 of 36
Last updated more than 3 months ago.