Food Ordering System Part 15 | How to Securely Delete User Accounts in ASP.NET Core MVC


In Part 15, we are implementing a vital security and privacy feature: Account Deletion. In a professional Food Ordering System, deleting a profile isn't just about removing a row from a table; it requires checking for active business logic—like making sure the customer doesn't have a pizza currently being prepared!


Step-by-Step Code Explanation

  1. Identity Verification: As with our update method, we first pull the UserId from the session. If the session is empty, we redirect them to the Login page to prevent unauthorized access.

  2. The "Active Order" Guard: This is a brilliant piece of business logic. Before deleting, the code checks the Orders table. If the user has any order with a status of "Pending", "Confirmed", or "Preparing", the deletion is blocked. We can't delete a user if a delivery driver is still looking for their address!

  3. Database Removal:

    • _context.Users.Remove(user): This marks the user record for deletion.

    • _context.SaveChanges(): This triggers the SQL DELETE command to permanently remove the account from your database.

  4. Session Cleanup: Once the account is gone, we must call HttpContext.Session.Clear(). This "logs out" the user immediately so they can no longer access protected pages.

  5. Final Redirect: The user is sent back to the Home Page with a TempData success message confirming their account has been removed.

 

ACCOUNTCONTROLLER.CS (DELETE ACTION)
[HttpPost]
public IActionResult DeleteAccount()
{
    var userId = HttpContext.Session.GetInt32("UserId");
    if (userId == null) return RedirectToAction("Login");

    var user = _context.Users.Find(userId);
    if (user == null) return NotFound();

    // Optional: Check if user has pending orders
    var pendingOrders = _context.Orders.Any(o => o.UserId == userId &&
        (o.Status == "Pending" || o.Status == "Confirmed" || o.Status == "Preparing"));

    if (pendingOrders)
    {
        TempData["Error"] = "Cannot delete account while you have active orders!";
        return RedirectToAction("Profile");
    }

    _context.Users.Remove(user);
    _context.SaveChanges();

    HttpContext.Session.Clear();
    TempData["Success"] = "Your account has been deleted.";
    return RedirectToAction("Index", "Home");
}

we are adding a critical safety layer to our application. In professional web development, "destructive" actions—like deleting an account—should never happen with a single accidental click. This Bootstrap Confirmation Modal provides a "speed bump" that ensures the user truly intends to remove their data.


Step-by-Step Code Explanation

  1. Bootstrap Modal Structure: The modal fade and modal-dialog classes create a popup window that sits on top of the Profile page. It remains hidden until the user clicks the "Delete Account" button we added earlier.

  2. id="deleteModal": This ID must match the data-bs-target="#deleteModal" attribute on the trigger button. This is how the browser knows which popup to open.

  3. Visual Warnings:

    • bg-danger: The red header immediately signals to the user that they are entering a "danger zone."

    • Iconography: The bi-exclamation-triangle-fill adds a professional visual warning.

  4. Clear Communication: The text explicitly states that "this action cannot be undone," which is vital for UX and transparency.

  5. The Hidden Form: Inside the modal-footer, we wrap the final delete button in a <form asp-action="DeleteAccount" method="post">. This ensures that when the user confirms, it sends a secure POST request to the controller action we created in the previous step.

VIEWS/ACCOUNT/DELETE_MODAL.HTML
<!-- Delete Account Modal -->
<div class="modal fade" id="deleteModal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header bg-danger text-white">
                <h5 class="modal-title">Delete Account</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                <p class="text-danger"><i class="bi bi-exclamation-triangle-fill"></i> <strong>Warning!</strong></p>
                <p>Are you sure you want to delete your account? This action cannot be undone!</p>
                <p>All your data including order history will be permanently removed.</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                <form asp-action="DeleteAccount" method="post">
                    <button type="submit" class="btn btn-danger">Yes, Delete My Account</button>
                </form>
            </div>
        </div>
    </div>
</div>

We are adding the trigger for our security system. While the modal handles the "Are you sure?" logic, this Delete Account Button serves as the entry point. It’s designed using Bootstrap 5 utility classes to look professional and stay out of the way until a user specifically looks for account settings.


Step-by-Step Code Explanation

  1. type="button": This is a crucial attribute. Since this button is located inside an HTML <form>, setting it to type="button" prevents it from accidentally submitting the "Save Changes" form. It only exists to trigger the modal.

  2. class="btn btn-outline-danger": We use the "outline" variant of the danger theme. This keeps the UI clean and less aggressive, only turning solid red when the user hovers over it.

  3. data-bs-toggle="modal": This is a Bootstrap data attribute that tells the JavaScript library to open a popup window when this button is clicked.

  4. data-bs-target="#deleteModal": This links the button to the specific ID of the modal we created. Without this exact match, the button won't do anything.

  5. bi bi-trash: We include a Bootstrap Icon to provide a clear visual cue that this button is for a destructive or "removal" action.

PROFILE.CSHTML (DELETE TRIGGER)
<button type="button" class="btn btn-outline-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">
    <i class="bi bi-trash"></i> Delete Account
</button>

Comments