Search code examples
c#asp.net.netasp.net-mvcrazor

NullReferenceException after deleting item from database, then redirecting to page showing the list of remaining items


I am getting a

System.NullReferenceException: Object reference not set to an instance of an object.

when I delete an item from the SQLite database and I redirect to the Index page (which shows the list of items) via the function in the controller class.

The item does successfully delete from the database, and when I manually go to the Index page (by clicking in the navbar link) it works fine without errors and the list appears updated, but when I redirect automatically using the function in the controller, thats when the System.NullReferenceException: Object reference not set to an instance of an object. occurs.

My problem is that I don't know how to fix this (I'm new to C# ASP.NET), but I can point out where the exception occurs in the example below on the Index.cshtml page. I am using C#, ASP.NET 7, Razor Pages, SQLite

The relevant codes are here:

  • CategoriesController.cs

DeleteConfirmed method which triggers the delete event and redirect to the Index page

// POST: Categories/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
    await _logic.RemoveCategoryFromProducts(id);
    await _logic.RemoveCategory(id);
    return View("Index");
}

Index method to get the Index page

public async Task<IActionResult> Index()
{
    var categories = await _logic.GetAllCategories();
    return View(categories);
}

**

  • Index.cshtml- the null reference exception occurs on the @foreach (var item in Model!) because it gets a null reference when redirected via the function above, but when I open this page manually, the list is updated successfully.**
@using Microsoft.EntityFrameworkCore
@model IEnumerable<CategoryModel>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action="Create" class="btn btn-info" role="button">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model!) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Feel free to ask if you need any more code examples, it's my first question I've asked on StackOverflow so please don't mind :)


Solution

  • The return View("Index"); line does not make redirect but renders the specified view. To make redirect use:

    return RedirectToAction("Index");
    

    RedirectToAction Method