BooksController.cs
(Cont.)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
Task
class represents a single operation that does not return a value and that usually executes asynchronously.
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
// GET: Books public async Task<IActionResult> Index( ) { return View( await _context.Book.ToListAsync( ) ); } |
async Task<IActionResult>
async
keyword marks a method as asynchronous, enabling the use of await
within it.
await _context.Book.ToListAsync( )
await
keyword pauses the execution of the method until the awaited task completes, without blocking the thread.
ToListAsync
method to creates a List<T>
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
id
might not always have a value, such as optional foreign keys or when the value is not yet assigned.
return NotFound( );
NotFoundResult
that produces a Status404NotFound
response.
FirstOrDefaultAsync
FirstOrDefaultAsync()
method asynchronously returns the first element of a sequence, or a default value if the sequence contains no elements.
m => m.Id == id
=>
): This separates the input parameters from the expression body.
m
: This is a parameter representing an object, such as a row in a database table or an item in a list.
m.Id
: This refers to the “Id
” property of the object represented by “m
.” This is commonly used for a primary key.
==
: This is the equality operator, comparing the value of m.Id
with the value of id.
id
: This is a variable that typically holds the ID you are trying to match.
return View( book );
View()
method can also accept a model object as an argument, which allows you to pass data from the controller to the view for rendering.
// POST: Books/Create [ 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 ); } |
[ HttpPost ]
[HttpPost]
attribute is used to indicate that a particular action method in a controller should only respond to HTTP POST requests.
[ ValidateAntiForgeryToken ]
[ValidateAntiForgeryToken]
attribute is a security feature used to prevent Cross-Site Request Forgery (CSRF) attacks. It ensures that an incoming HTTP request originated from a form on your website rather than a malicious third-party site.
Bind( "Id, Title, Genre, Price, PublishDate" )..;
using ..;
using ..;
using ..;
|
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 http://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 http://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 ); } } } |
“By the time a man is wise enough to watch his step, he’s too old to go anywhere.” — Billy Crystal on aging |