0

Not a Duplicate: See the comment and answer to this question.

I am almost new to ASP.net Core development. I am building a sample web api with MySql as my database.

My Book model:

public class Book
    {   
        [Key]
        public long Id { get; set; }
        [Required]
        public string Name { get; set; }
        [Required]
        public string Author { get; set; }
        public DateTime CreatedOn { get; set; } = DateTime.UtcNow;

        public Book()
        {

        }
    }

    public class WebAPIDataContext : DbContext
    {
        public WebAPIDataContext(DbContextOptions<WebAPIDataContext> options)
            : base(options)
        {
        }
        public DbSet<Book> Books { get; set; }
    }

Book Repository:

public class BookRepository: IBookRepository
    {
        private readonly WebAPIDataContext _db;

        public BookRepository(WebAPIDataContext db) {
            _db = db;
        }

        public Book CreateBook(Book book) {
            _db.Books.Add(book);
            _db.SaveChanges();
            return book;
        }

        public void DeleteBook(long id)
        {
            Book book = GetBook(id);
            if (book != null) {
                _db.Books.Remove(book);
                _db.SaveChanges();
            }
        }

        public List<Book> GetAllBooks()
        {
            return _db.Books.AsNoTracking().ToList();
        }

        public Book GetBook(long id)
        {
            return _db.Books.FirstOrDefault(o => o.Id == id);
        }

        public void UpdateBook(long id, Book book)
        {
            throw new NotImplementedException();
        }
    }

    public interface IBookRepository
    {
        List<Book> GetAllBooks();
        Book GetBook(long id);
        Book CreateBook(Book book);
        void UpdateBook(long id, Book book);
        void DeleteBook(long id);
    }

And Book controller:

[Route("api/[controller]")]
    public class BooksController : Controller
    {
        private readonly IBookRepository _books;

        [HttpGet("")]
        public IActionResult GetAllBooks()
        {
            List<Book> books = _books.GetAllBooks();
            return Ok(books);
        }

        [HttpGet("{id}")]
        public IActionResult GetBook(long id)
        {
            Book book = _books.GetBook(id);
            if (book == null)
            {
                return NotFound();
            }
            return Ok(book);
        }

        [HttpPost]
        public IActionResult CreateBook([FromBody] Book book)
        {
            if (ModelState.IsValid == false)
            {
                return BadRequest(ModelState);
            }

            Book createdBook= _books.CreateBook(book);

            return CreatedAtAction(
                nameof(GetBook), new { id = createdBook.Id }, createdBook);
        }

        [HttpPut("{id}")]
        public IActionResult UpdateBook(long id, [FromBody] Book book)
        {
            if (ModelState.IsValid == false)
            {
                return BadRequest(ModelState);
            }

            try
            {
                _books.UpdateBook(id, book);
                return Ok();
            }
            catch (EntityNotFoundException<Book>)
            {
                return NotFound();
            }
        }

        [HttpDelete("{id}")]
        public IActionResult DeleteBook(long id)
        {
            _books.DeleteBook(id);
            return Ok();
        }
    }

When I do a POST request from Swagger to create a new book it gives me NullReferenceException error. What am I doing wrong?

Thinker
  • 4,664
  • 9
  • 48
  • 119
  • Well I tried handling null as suggested at this post but didn't help. – Thinker Mar 16 '17 at 17:32
  • Where do you assign _books in the controller class to the implementation? Right now it doesn't have a initialized state at runtime. And it doesn't happen unless you do it in the constructor with DI assuming is the route you were attempting to go. not a Dupe... just a misunderstanding of why in his case. – mvermef Mar 16 '17 at 17:34
  • This is my very first attempt with ASP.net Core and I was following (https://joonasw.net/view/building-a-basic-web-api-on-asp-net-core) this tutorial. I basically tried the same logic as his but with different model. Perhaps you could give me the right way? – Thinker Mar 16 '17 at 17:40

1 Answers1

1

For this first case to work you needed to have

services.AddScoped<IBookRepository, BookRepository>();

in ConfigureServices method located in the startup.cs

public class BooksController : Controller
{
   public BooksController(IBookRepository books){
       _books = books;
   }
   ...

Now this assumes you hooked up your IBookRepository to be included in the container for Asp.NET Core in the startup class.

IF NOT then this is what you are missing!

public class BooksController : Controller
{
   public BooksController(){
       _books = new BookRepository();
   }

If you have never worked with Dependency Injection before this I suggest you read up on it, also goes by IOC (inversion of control).

mvermef
  • 3,505
  • 1
  • 21
  • 33