The view expects Model.BookList to not be null. The list will not be included in the postback data, so it is null. The postback code should recreate the list before calling the view.
Null Reference Exception while using an EFCore List ?
Hi everyone,
I'm facing an issue of "Null Reference Exception" when I submit an empty Form whereas I did a ModelState verification. (see my HomeController and Index page)
The exact error occurs when the breakpoints hits line 40 inside HomeController and I get :
NullReferenceException: Object reference not set to an instance of an object.
AspNetCore.Views_Home_Index.<ExecuteAsync>b__14_0() in Index.cshtml
+
@foreach (var book in @默 .BookList)
Indeed here is my code :
IndexViewModel.cs :
using System.Collections.Generic;
using Blog.Models;
namespace Blog.ViewModels.Home
{
public class IndexViewModel
{
public BookViewModel BookViewModel { get; set; }
public List<Book> BookList { get; set; }
}
}
BookViewModel.cs :
using System.ComponentModel.DataAnnotations;
namespace Blog.ViewModels.Home
{
public class BookViewModel
{
[Required(ErrorMessage = "Please specify a name")]
[Display(Name = "Name : ")]
public string Name { get; set; }
[Required(ErrorMessage = "Please specify a price")]
[Display(Name = "Price : ")]
public int Price { get; set; }
}
}
Index.cshtml :
@model Blog.ViewModels.Home.IndexViewModel
@{
ViewData["Title"] = "Blog";
Layout = "_Layout";
}
@section page_content{
<p>Hello World form Blog !</p>
<form asp-controller="Home" asp-action="Index" method="post">
<label asp-for="@Model.BookViewModel.Name"></label>
<input asp-for="@Model.BookViewModel.Name">
<span asp-validation-for="@Model.BookViewModel.Name"></span>
<label asp-for="@Model.BookViewModel.Price"></label>
<input asp-for="@Model.BookViewModel.Price">
<span asp-validation-for="@Model.BookViewModel.Price"></span>
<input type="submit" value="Continuer">
</form>
<table>
<thead>
<th>
<td>Name</td>
<td>Price</td>
</th>
</thead>
<tbody>
@foreach (var book in @Model.BookList)
{
<tr>
<td>@book.Name</td>
<td>@book.Price</td>
</tr>
}
</tbody>
</table>
}
HomeController.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Blog.Data;
using Blog.Models;
using Blog.ViewModels.Home;
using Microsoft.AspNetCore.Mvc;
namespace Blog.Controllers
{
public class HomeController : Controller
{
private readonly BookDbContext _bookDbContext;
public HomeController(BookDbContext bookDbContext)
{
_bookDbContext = bookDbContext;
}
public IActionResult Index()
{
var indexViewModel = new IndexViewModel();
var bookList = _bookDbContext.Book.ToList();
if(bookList != null)
{
indexViewModel.BookList = bookList;
System.Console.WriteLine("BookList was not null => " + indexViewModel.BookList.ToString());
}
return View(indexViewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Index(IndexViewModel indexViewModel)
{
if(!ModelState.IsValid)
{
// Null Reference Exception is triggered below
System.Console.WriteLine("Book CreationForm was not valid");
return View(indexViewModel);
}
var new_book = new Book{
Name = indexViewModel.BookViewModel.Name,
Price = indexViewModel.BookViewModel.Price
};
await _bookDbContext.AddAsync(new_book);
await _bookDbContext.SaveChangesAsync();
return RedirectToAction("Index", "Home");
}
}
}
Thanks in advance for your help
Developer technologies ASP.NET ASP.NET Core
1 additional answer
Sort by: Most helpful
-
Valenciano8 116 Reputation points
2021-07-24T23:03:06.827+00:00 Hi @Bruce Barker , you were right, thank you !
Here is my updated code which now works :)
using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Blog.Data; using Blog.Models; using Blog.ViewModels.Home; using Microsoft.AspNetCore.Mvc; namespace Blog.Controllers { public class HomeController : Controller { private readonly BookDbContext _bookDbContext; public HomeController(BookDbContext bookDbContext) { _bookDbContext = bookDbContext; } public IActionResult Index() { var indexViewModel = new IndexViewModel(); var bookList = _bookDbContext.Book.ToList(); if(bookList != null) { indexViewModel.BookList = bookList; System.Console.WriteLine("BookList was not null => " + indexViewModel.BookList.ToString()); } return View(indexViewModel); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Index(IndexViewModel indexViewModel) { if(!ModelState.IsValid) { indexViewModel.BookList = _bookDbContext.Book.ToList(); return View(indexViewModel); } var new_book = new Book{ Name = indexViewModel.BookViewModel.Name, Price = indexViewModel.BookViewModel.Price }; await _bookDbContext.AddAsync(new_book); await _bookDbContext.SaveChangesAsync(); return RedirectToAction("Index", "Home"); } } }