In this recipe, we are going to present a list of data with an option to delete one of the records. When the user clicks on the link to delete a record, they will be taken to a page confirming that they actually want to delete the record. From there, the user can post the ID to the controller and actually perform the delete on the record they selected.
This recipe will build from the first recipe. By that I mean to say that we will be using the Product
class and ProductRepository
along with NBuilder to generate our data for us.
Product
and ProductRepository
class in our Models
folder (you can get this from any of the previous recipes). ProductRepository
and add a method called GetProduct
in addition to the existing GetProducts
method.ProductRepository.cs:
public Product GetProduct(int productId) { Product product = Builder<Product>.CreateNew().With(x=>x.ProductId = productId).Build(); return product; }
Controllers/HomeController.cs:
public ActionResult Index() { ViewData["Message"] = "Welcome to ASP.NET MVC!"; ViewData["Products"] = new ProductRepository().GetProducts(); return View(); }
Views/Home/Index.aspx:
<fieldset> <legend>Products</legend> <% List<Product> products = ViewData["Products"] as List<Product>; %> <% foreach (Product p in products) { %> <div class="display-label"> <%= Html.ActionLink("Delete", "ConfirmDelete", new {@id=p.ProductId}) %> </div> ... <hr /> <% } %> </fieldset>
ConfirmDelete
action. Let's add that now. In the home controller we will add a new action called ConfirmDelete
. This action will instantiate the appropriate Product
and pass it down to the view to prompt the user to be sure that they want to delete that record or not.Controllers/HomeController.cs:
public ActionResult ConfirmDelete(int id) { Product product = new ProductRepository().GetProduct(id); return View(product); }
ConfirmDelete
method name and choose to add a new view. Make this view strongly typed to the Product
class and select the details view. Then open up the new view and add this form to the top of the page, which will allow the user to post their request to delete the appropriate record.Views/Home/ConfirmDelete.aspx:
<% using(Html.BeginForm("Delete", "Home", new {@id=Model.ProductId})) {%> <div> Are you sure you want to delete this record?<br/> <%= Html.HiddenFor(m=>m.ProductId) %> <input type="submit" value="Delete Record!" /> </div> ... }
ProductID
to the delete action where the appropriate data deletion logic can be placed. Let's add that new action now. Notice that we are enforcing this action to accept posted data only with the [HttpPost]
attribute.Controllers/HomeController.cs:
[HttpPost] public ActionResult Delete(int id) { //perform delete logic on your data return View(); }
Delete
action and select Add View. This view can either be strongly typed or not...that is up to you. Add a message in your view letting your user know that you have to delete the record as they requested. I also provided a link back to the home page.Views/Home/Delete.aspx:
<h2>Record Deleted</h2> <%= Html.ActionLink("Home", "Index") %>
This recipe is more of a lesson in workflow rather than complex cutting edge technology! In this recipe we listed some data. Each piece of data is linked to a deletion confirmation page, where we asked the user in a very Windows manner if they were sure they wanted to delete the specified bits of data. If they clicked the button to delete the data, we deleted it and told the user that we did so.
It is important to note however that we did not perform the deletion on a GET
request (standard HTML link requesting a page). You should stay away from GET
requests that perform any action on your application other than reading data. Instead, use a post to do actions such as deletes. Think of it this way...if Google were to spider your site and crawl a bunch of links that requested your delete links by way of a GET
request, you might wake up and find all your data deleted! There are of course other ways to stop this from happening but this is a quick and easy rule to remember, just in case things don't go as planned.