Confirming Delete Operations in ASP.NET MVC

WEBINAR: On-demand webcast

How to Boost Database Development Productivity on Linux, Docker, and Kubernetes with Microsoft SQL Server 2017 REGISTER >

Introduction

Seeking confirmation of some important action, such as deleting a record, is a common practice in web applications. There are two common approaches to seek confirmation from the end user. In the first approach a dialog box is displayed to the user seeking his consent to perform the delete operation and in the second approach the user is shown a separate confirmation page. In the former approach the control remains in the page where deletion is taking place whereas in the latter case control moves to a confirmation page and the actual deletion operation happens in the confirmation page. This article illustrates how both of these techniques can be implemented in ASP.NET MVC.

Which Technique to Use?

As discussed earlier there are two common ways to seek confirmation of a delete operation from the user :

  • Show a dialog box to the end user seeking his consent for the delete operation
  • Take the user to a confirmation page where he confirms the delete operation

Though there is no rigid rule as to which technique you should use, generally the first technique is used when the user is not supposed to review the entire record being deleted. Consider, for example, that you are working with an order processing system and there is a web page showing a list of past orders. Now the listing page might be showing only the partial information about the order. If a user deletes an order without reviewing the complete details of the order chances are that he is unaware of possible consequences of deleting the record. It would be desirable that he is presented with the complete order history along with notes, comments and special instructions about the order before he deletes it. In such cases the first way of confirming deletes is inadequate and you might prefer to use the second technique. The second technique may also be required in situations where you wish to use a minimum or no client side script.

Creating a Sample Application

In order to illustrate both of the techniques discussed above, you will develop a sample ASP.NET MVC application. To begin with, create an empty ASP.NET MVC application using ASPX view engine. The sample application will use the Employees table from the Northwind database and you will need to create an Entity Framework data model for the same. So, add a new ADO.NET Entity Data Model in the Models folder and then drag and drop the Employees table on it. Doing so will create a model as shown below :

Add a new ADO.NET Entity Data Model
Figure 1: Add a new ADO.NET Entity Data Model

Confirming Deletes Without Leaving the Current Page

Once the data model is ready add a new controller class and name it Home. Add an action method - Index() - as shown below :

public ActionResult Index()

{

    NorthwindEntities db=new NorthwindEntities();

    var data = from item in db.Employees

                select item;

    ViewBag.Employees = data;

    return View();

}

As you can see, the Index() action method fetches all of the employees and stores the collection in a ViewBag property (Employees). Then right click on the Index() action method and add a view named Index. The Index view will display all of the employee records and will have links to delete a record. The Index view as shown in the browser looks like this :

Index View of Employee Listing
Figure 2: Index View of Employee Listing

The HTML markup of Index view is shown below :

<h2>Employee Listing</h2>

<%

using (Html.BeginForm()){

%>

<table border="1" cellpadding="5">

<% 

foreach(var item in ViewBag.Employees)

{

%>

<tr>

<td><%= item.EmployeeID %></td>

<td><%= item.FirstName %></td>

<td><%= item.LastName %></td>

<td><%= Html.ActionLink("Delete", "Delete", new { @employeeid = item.EmployeeID }, new { @class="delete", @id=item.EmployeeID })%></td>

</tr>

<%

}

%>

</table>

<%

}

%>

As you can see, the view essentially renders a table and displays FirstName and LastName columns. It also renders a hyperlink to initiate the delete operation. Notice that ID attribute of the hyperlink is set to EmployeeID so that you can detect the employee ID to be deleted later in the code. Also, the hyperlink is assigned a CSS class named delete. This is done so that your client side code can distinguish delete hyperlinks from rest of the hyperlinks from the page.

Next, add an action method - DeleteAJAX() - that deletes a specified employee record as shown below :

[HttpPost]

public JsonResult DeleteAJAX(int employeeid)

{

  NorthwindEntities db = new NorthwindEntities();

  Employee data = (from item in db.Employees

                   where item.EmployeeID == employeeid

                   select item).SingleOrDefault();

  db.Employees.DeleteObject(data);

  db.SaveChanges();

  return Json("Record deleted successfully!");

}

The DeleteAJAX() action method is intended to be called from client side jQuery code and hence its return type is JsonResult. Inside, it deletes an employee record based on the EmployeeID passed to it and returns a string message to the caller.

In this technique you will be using jQuery to call the DeleteAJAX() action method. So, add a script reference to jQuery library.

<script src="../../Scripts/jquery-1.4.4.js" type="text/javascript"></script>

Then add a script block and write the following code in it :

    <script type="text/javascript">

        $(document).ready(function () {

            $('a.delete').click(OnDeleteClick);

        });

 

        function OnDeleteClick(e)

        {

            var employeeId = e.target.id;

            var flag = confirm('You are about to delete Employee ID ' + employeeId + ' permanently. 

                                Are you sure you want to delete this record?');

            if (flag) {

                $.ajax({

                    url: '/home/DeleteAJAX',

                    type: 'POST',

                    data: { employeeid: employeeId },

                    dataType: 'json',

                    success: function (result) { alert(result); $("#" + employeeId).parent().parent().remove(); },

                    error: function () { alert('Error!'); }

                });

            }

            return false;

        }

    </script>    

The ready() function wires click the event handler of the delete hyperlinks to the OnDeleteClick function. Notice how the delete hyperlinks are filtered using the class name we assigned earlier. The OnDeleteClick() function retrieves the ID of the delete link being clicked, using the target.id property. It then seeks confirmation from the user using the confirm() JavaScript function. If the user clicks on OK, an AJAX call is made to the DeleteAJAX() action method using jQuery $.ajax(). Notice how the options of $.ajax() are specified. The url parameter indicates the URL of the action method to be called, type parameter specifies the method to be used (POST) for calling the action method. The data parameter is the JSON representation of the employee ID to be deleted. Recollect that employeeid is the parameter name of the DeleteAJAX() action method. When the remote action method completes successfully a function, as specified by the success parameter, will be called. In the above example, the success function simply displays the message as returned by the DeleteAJAX() method. The concerned table row is then removed using the remove() method. This way the deleted record will be removed from the table. Notice the use of the parent() method. Since the delete hyperlink is inside a <td> which is inside a <tr> you need to use it twice to remove the table row.

Now, run the index view and try deleting a record. The following figure shows the index view after a delete attempt.

The index view after a delete attempt
Figure 3: The index view after a delete attempt

Confirming Deletes by Navigating to a Confirmation Page

In the second technique of confirming deletes you will display an intermediate confirmation page before deleting a record. In order to implement this technique you need to add the following two action methods in the Home controller.

public ActionResult ConfirmDelete(int employeeid)

{

    NorthwindEntities db=new NorthwindEntities();

    var data = from item in db.Employees

                where item.EmployeeID == employeeid

               select item;

    Employee employee = data.SingleOrDefault();

    return View(employee);

}

 

[HttpPost]

public ActionResult Delete(int employeeid)

{

    NorthwindEntities db = new NorthwindEntities();

    Employee data=(from item in db.Employees

                where item.EmployeeID == employeeid

                select item).SingleOrDefault();

    db.Employees.DeleteObject(data);

    db.SaveChanges();

    return View();

}

In the previous example you called the DeleteAJAX() method directly from the client side code. In this case the delete operation will not happen from the employee listing page. When a user clicks on the delete link, he will be taken to the ConfirmDelete view wherein delete confirmation is sought. On the delete confirmation page you will display details such as EmployeeID, FirstName, LastName and Notes so that the user can review the record being deleted. The ConfirmDelete() action method essentially retrieves an employee's information and passes it to the ConfirmDelete view. The ConfirmDelete view then calls the Delete() action method if the user decides to delete that record. The Delete() action method simply deletes an employee record from the database.

After completing the ConfirmDelete() and Delete() action methods, right click on them one by one and add the respective views. While creating the ConfirmDelete view make sure to create a strongly typed view based on Employee class.

ConfirmDelete
Figure 4: ConfirmDelete

The following figure and HTML markup shows what the ConfirmDelete view looks like.

ConfirmDelete View
Figure 5: ConfirmDelete View

<% using (Html.BeginForm("Delete", "Home", FormMethod.Post))

{

%>

<h2>Warning!</h2>

You are about to delete the following Employee record :

<br /><hr />

<strong>

<%= Model.EmployeeID + ". " + Model.FirstName + " " + Model.LastName %>

<br />

<%= Model.Notes %>

</strong>

<br/><hr />

Are you sure you want to delete this record?

<br/>

<%= Html.HiddenFor(m => m.EmployeeID)%>

<input type="submit" value="Delete" />

<input type="button" value="Cancel" onclick="OnCancelClick();" />

<%} %>

As you can see, the ConfirmDelete view receives an employee instance as a Model. It then displays EmployeeID, FirstName, LastName and Notes. Notice that the HTML form will be submitted to the Delete() action method as indicated in the BeginForm(). Also notice the use of a hidden form field for storing EmployeeID. This way when the form is submitted the Delete() action method will receive the EmployeeID to be deleted. Clicking on the Cancel button will call a JavaScript function OnCancelClick() that will simply take the user to the employee listing page. The OnCancelClick() function is shown below.

 function OnCancelClick() {
     window.location.href = '/home/index';
}

The ConfirmDelete action method needs to be wired with the Delete hyperlinks of the Index view. So, modify the ActionLink() call that renders the Delete link as follows :

<%= Html.ActionLink("Delete","ConfirmDelete",new { @employeeid = item.EmployeeID })%>

The Delete view simply displays a message informing successful record deletion.

Record Deleted
Figure 6: Record Deleted

 <h2>Record Deleted!</h2>

<%= Html.ActionLink("Back to Employee Listing", "Index") %>

That's it! Now run the Index view and click on any of the Delete links. You will be taken to the ConfirmDelete view wherein you can delete the record. 

Summary

Seeking confirmation from the user prior to deleting a record is a common practice in web applications. There can be multiple ways to implement this functionality in a web page. This article covered two popular techniques of confirming deletes in an ASP.NET MVC application. You can customize or modify the techniques illustrated here to suit your requirements.



About the Author

Bipin Joshi

Bipin Joshi is a blogger and writes about apparently unrelated topics - Yoga & technology! A former Software Consultant by profession, Bipin has been programming since 1995 and has been working with the .NET framework ever since its inception. He has authored or co-authored half a dozen books and numerous articles on .NET technologies. He has also penned a few books on Yoga. He was a well known technology author, trainer and an active member of Microsoft developer community before he decided to take a backseat from the mainstream IT circle and dedicate himself completely to spiritual path. Having embraced Yoga way of life he now codes for fun and writes on his blogs. He can also be reached there.

Related Articles

Downloads

Comments

  • Thanks for your tutorial

    Posted by Stella James on 11/20/2015 03:10am

    Thanks for sharing your tutorial.

    • Sudha j

      Posted by Sudha j on 12/22/2015 11:42pm

      thank u very much

      Reply
    Reply
  • What does "back To Employee Listing" Do?

    Posted by FanFarron on 03/25/2014 11:21am

    The view contains this : "Html.ActionLink("Back to Employee Listing", "Index")" However, if you were to click on the link, the listing would then be displayed in that window right? That is, the original window where the user clicked to get to the Delete Confirmation window is no longer accessible. I am looking for a way that upon completion of the deletion, control could be returned to the original window. I am using MVC4 for my application. Any feedback/guidance/comments would be greatly appreciated.

    Reply
  • Pictures missing

    Posted by Rubem Nascimento da Rocha on 02/28/2013 01:29am

    The article's pictures are missing. I can't view them.

    Reply
  • Customize the confirmation window title

    Posted by Sam on 12/19/2012 09:11am

    Hello Bipin. Thanks for your useful post. Do you know any way to change the title of the confirmation window so it mentions something different than "The page at says:" ? Thanks Sam

    Reply
  • Appreciation

    Posted by Morteza on 04/16/2012 08:26am

    Awesome as always! Thanks

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date