when I select a list of data from database i get error An unhandled exception occurred while processing the request. NullReferenceException: Object reference not set to an instance of an object. Bookstore.Models.Repositories.BookDbRepository.List() in BookDbRepository.cs, line 38
BookController
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Bookstore.Models.Repositories;
using Bookstore.Models;
using Bookstore.ViewModels;
using Microsoft.AspNetCore.Hosting;
using System.IO;
namespace Bookstore.Controllers
{
public class BookController : Controller
{
private readonly IBookstorerRepository<Book> bookRepository;
private readonly IBookstorerRepository<Author> authorRepository;
private readonly IHostingEnvironment hosting;
public BookController(IBookstorerRepository<Book> bookRepository, IBookstorerRepository<Author> authorRepository,IHostingEnvironment hosting)
{
this.bookRepository = bookRepository;
this.authorRepository = authorRep
ository;
this.hosting = hosting;
}
// GET: BookController
public ActionResult Index()
{
var book = bookRepository.List();
return View(book);
}
// GET: BookController/Details/5
public ActionResult Details(int id)
{
var book = bookRepository.Find(id);
return View(book);
}
// GET: BookController/Create
public ActionResult Create()
{
return View(GetallAuthors());
}
// POST: BookController/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(BookAuthor model)
{
if (ModelState.IsValid)
{
try
{
string FileName = string.Empty;
if(model.file != null)
{
string uploads = Path.Combine(hosting.WebRootPath,"uploads");
FileName = model.file.FileName;
string FullPath = Path.Combine(uploads, FileName);
model.file.CopyTo(new FileStream(FullPath, FileMode.Create));
}
if (model.AuthorId == -1)
{
ViewBag.message = "please select an author";
return View(GetallAuthors());
}
var author = authorRepository.Find(model.AuthorId);
Book book = new Book
{
Id = model.BookId,
Title = model.Title,
Description = model.Description,
ImageUrl = FileName,
Author = author
};
bookRepository.Add(book);
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
ModelState.AddModelError("", "you hav to fill all required data");
return View(GetallAuthors());
}
// GET: BookController/Edit/5
public ActionResult Edit(int id)
{
var book = bookRepository.Find(id);
var authorId = book.Author == null ? book.Author.Id = 0 : book.Author.Id;
var viewmodel = new BookAuthor()
{
BookId=book.Id,
Title=book.Title,
Description=book.Description,
AuthorId= authorId,
Authors=authorRepository.List().ToList(),
ImageUrl=book.ImageUrl
};
return View(viewmodel);
}
// POST: BookController/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id, BookAuthor viewmodel)
{
try
{
string FileName = string.Empty;
if (viewmodel.file != null)
{
string uploads = Path.Combine(hosting.WebRootPath, "uploads");
FileName = viewmodel.file.FileName;
string FullPath = Path.Combine(uploads, FileName);
//delete old file
string oldfilename = bookRepository.Find(viewmodel.BookId).ImageUrl;
string fulloldpath = Path.Combine(uploads, oldfilename);
if(FullPath != fulloldpath)
{
System.IO.File.Delete(fulloldpath);
//save new file
viewmodel.file.CopyTo(new FileStream(FullPath, FileMode.Create));
}
}
var author = authorRepository.Find(viewmodel.AuthorId);
Book book = new Book
{
Title = viewmodel.Title,
Description = viewmodel.Description,
Author = author,
ImageUrl = FileName
};
bookRepository.Update(viewmodel.BookId,book);
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
// GET: BookController/Delete/5
public ActionResult Delete(int id)
{
var book = bookRepository.Find(id);
return View(book);
}
// POST: BookController/Delete/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ConfirmDelete(int id)
{
try
{
bookRepository.Delete(id);
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
List<Author> fillselectlist()
{
var Authors = authorRepository.List().ToList();
Authors.Insert(0, new Author { Id = -1, fullname = "... please select item ..." });
return Authors;
}
BookAuthor GetallAuthors()
{
var viewmodel = new BookAuthor
{
Authors = fillselectlist()
};
return viewmodel;
}
}
}
Book class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Bookstore.Models
{
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
public Author Author { get; set; }
}
}
BookDbRepository
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace Bookstore.Models.Repositories
{
public class BookDbRepository : IBookstorerRepository<Book>
{
BookstoreDbContext db;
public BookDbRepository(BookstoreDbContext _db)
{
_db = db;
}
public void Add(Book entity)
{
db.Books.Add(entity);
db.SaveChanges();
}
public void Delete(int id)
{
var book = Find(id);
db.Books.Remove(book);
db.SaveChanges();
}
public Book Find(int id)
{
var book = db.Books.SingleOrDefault(b => b.Id == id);
return book;
}
public IList<Book> List()
{
return db.Books.Include(a=>a.Author).ToList();
}
public void Update(int id, Book newbook)
{
db.Books.Update(newbook);
db.SaveChanges();
}
Startup
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Bookstore.Models.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Bookstore.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.EntityFrameworkCore;
namespace Bookstore
{
public class Startup
{
private readonly IConfiguration configuration;
public Startup(IConfiguration configuration)
{
this.configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options => options.EnableEndpointRouting = false);
services.AddScoped<IBookstorerRepository<Author>, AuthorDbRepository>();
services.AddScoped<IBookstorerRepository<Book>, BookDbRepository>();
services.AddDbContext<BookstoreDbContext>(options =>
{
options.UseSqlServer(configuration.GetConnectionString("SqlCon"));
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvcWithDefaultRoute();
app.UseStaticFiles();
}
}
}
}
}
I get this error An unhandled exception occurred while processing the request. NullReferenceException: Object reference not set to an instance of an object. Bookstore.Models.Repositories.BookDbRepository.List() in BookDbRepository.cs, line 38
CodePudding user response:
You need to check that book
is not null in this action
public ActionResult Index()
{
var book = bookRepository.List();
if (book != null)
{
return View(book);
}
else
{
//do something, ex: throw an exception or return to an error page
}
}
CodePudding user response:
I get this error An unhandled exception occurred while processing the request. NullReferenceException: Object reference not set to an instance of an object. Bookstore.Models.Repositories.BookDbRepository.List() in BookDbRepository.cs, line 38
Well, the error you are getting may have two maain reason.
Reason:1
Either of your data in Book
or Author
table is empty.
Reason:2
You want to allow empty data row for author table
in views. which causing the error.
Solution:
If you want to handle empty result set
or null data
in controler you can modify your code as below:
public class BookStorerController : Controller
{
private readonly IBookstorerRepository _bookRepository;
public BookStorerController(IBookstorerRepository bookRepository)
{
_bookRepository = bookRepository;
}
public IActionResult Index()
{
var booklist = _bookRepository.List();
if (booklist.Count == 0 || booklist == null)
{
return Content("No data found!");
}
return View(booklist);
}
}
Note: This condition booklist.Count == 0 || booklist == null
will save your program to break while throw exception.
Solution: 2
You even cam handle the "NullReferenceException: Object reference not set to an instance of an object" in your class as well. In that case modidy the class as below:
public class Book
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public Author? Author { get; set; }
}
Solution: View
If you can handle null/empty
row in view you can do as below as well.
@item.Author?.Name
Or full view should be as following:
@model IEnumerable<DotNet6MVCWebApp.Models.Book>
<table >
<thead>
<tr>
<th>Book Id
<th>Title
<th>Description
<th>Author Name
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@item.Id</td>
<td>@item.Title</td>
<td>@item.Description</td>
<td>@item.Author?.Name</td>
</tr>
}
</tbody>
</table>
Output: