MVC Controllers: BooksController.cs (Cont.)

 // GET: Books
 public async Task<IActionResult> Index( ) {
   return View( await _context.Book.ToListAsync( ) );
 }
async Task<IActionResult>
The keyword marks a method as asynchronous, enabling the use of within it.

await _context.Book.ToListAsync( )

  • The keyword pauses the execution of the method until the awaited task completes, without blocking the thread.
  • The method to creates a by enumerating it asynchronously.

 // GET: Books/Details/5
 public async Task<IActionResult> Details( int? id ) {
   if ( id == null ) { return NotFound( ); }
   var book = await _context.Book.FirstOrDefaultAsync( m => m.Id == id );
   if ( book == null ) { return NotFound( ); }
   return View( book );
 }

int? id
It means the might not always have a value, such as optional foreign keys or when the value is not yet assigned.

return NotFound( );
The method creates a NotFoundResult that produces a Status404NotFound response.

FirstOrDefaultAsync
The method asynchronously returns the first element of a sequence, or a default value if the sequence contains no elements.

m => m.Id == id
It is a lambda expression often used in data access technologies like LINQ (Language Integrated Query) and Entity Framework:


  • Lambda Operator (): This separates the input parameters from the expression body.
  • : This is a parameter representing an object, such as a row in a database table or an item in a list.
  • : This refers to the ; property of the object represented by . This is commonly used for a primary key.
  • : This is the equality operator, comparing the value of with the value of id.
  • : This is a variable that typically holds the ID you are trying to match.

return View( book );
The method can also accept a model object as an argument, which allows you to pass data from the controller to the view for rendering.
C:\ASP.NET-workspace\BookStore1\Controllers\BooksController.cs
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.Rendering;
 using Microsoft.EntityFrameworkCore;
 using BookStore1.Data;
 using BookStore1.Models;

 namespace BookStore1.Controllers {
   public class BooksController : Controller {
     private readonly BookStore1Context _context;
     public BooksController( BookStore1Context context ) { _context = context; }

     // GET: Books
     public async Task<IActionResult> Index( ) {
       return View( await _context.Book.ToListAsync( ) );
     }

     // GET: Books/Details/5
     public async Task<IActionResult> Details( int? id ) {
       if ( id == null ) { return NotFound( ); }
       var book = await _context.Book.FirstOrDefaultAsync( m => m.Id == id );
       if ( book == null ) { return NotFound( ); }
       return View( book );
     }

     // GET: Books/Create
     public IActionResult Create( ) { return View( ); }

     // POST: Books/Create
     // To protect from overposting attacks,
     //   enable the specific properties you want to bind to.
     // For more details, see https://go.microsoft.com/fwlink/?LinkId=317598.
     [ HttpPost ]
     [ ValidateAntiForgeryToken ]
     public async Task<IActionResult> Create(
         [ Bind( "Id, Title, Genre, Price, PublishDate" ) ] Book book ) {
       if ( ModelState.IsValid ) {
         _context.Add( book );
         await _context.SaveChangesAsync( );
         return RedirectToAction( nameof( Index ) );
       }
       return View( book );
     }

     // GET: Books/Edit/5
     public async Task<IActionResult> Edit( int? id ) {
       if ( id == null ) { return NotFound( ); }
       var book = await _context.Book.FindAsync( id );
       if ( book == null ) { return NotFound( ); }
       return View( book );
     }

     // POST: Books/Edit/5
     // To protect from overposting attacks,
     //   enable the specific properties you want to bind to.
     // For more details, see https://go.microsoft.com/fwlink/?LinkId=317598.
     [ HttpPost ]
     [ ValidateAntiForgeryToken ]
     public async Task<IActionResult> Edit( int id,
         [ Bind( "Id, Title, Genre, Price, PublishDate" ) ] Book book ) {
       if ( id != book.Id ) { return NotFound( ); }
       if ( ModelState.IsValid ) {
         try {
           _context.Update( book );
           await _context.SaveChangesAsync( );
         }
         catch ( DbUpdateConcurrencyException ) {
           if ( !BookExists( book.Id ) ) { return NotFound( ); }
           else { throw; }
         }
         return RedirectToAction( nameof( Index ) );
       }
       return View ( book );
     }

     // GET: Books/Delete/5
     public async Task<IActionResult> Delete( int? id ) {
       if ( id == null ) { return NotFound( ); }
       var book = await _context.Book.FirstOrDefaultAsync( m => m.Id == id );
       if ( book == null ) { return NotFound( ); }
       return View( book );
     }

     // POST: Books/Delete/5
     [ HttpPost, ActionName( "Delete" ) ]
     [ ValidateAntiForgeryToken ]
     public async Task<IActionResult> DeleteConfirmed( int id ) {
       var book = await _context.Book.FindAsync( id );
       if ( book != null ) { _context.Book.Remove( book ); }
       await _context.SaveChangesAsync( );
       return RedirectToAction( nameof( Index ) );
     }

     private bool BookExists( int id ) {
       return _context.Book.Any( e => e.Id == id );
     }
   }
 }




      “I bought a dog the other day. I named him Stay.    
      It’s fun to call him. ‘Come here, Stay! Come here, Stay!’    
      He went insane.”    
      — Carrot Top