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" )..;
[Bind]
attribute is used to control which properties of a model are included or excluded during model binding.
ModelState.IsValid;
IsValid
property is used for model validation within controller actions. It returns true if the submitted model data adheres to all the validation rules defined on its properties, and false otherwise.
_context.Add( book );
await _context.SaveChangesAsync( );
_context.Add
method is used to add an entity to the database context.
This method marks the entity as “Added,” meaning it will be inserted into the database when calls the SaveChangesAsync
method, which allows you to asynchronously save changes made to the database context.
RedirectToAction( nameof( Index ) )
RedirectToAction
method redirects to the specified action using the action name.
The nameof
operator is used to obtain the name of a variable, type, or member as a string.
// 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 ); } |
await _context.Book.FindAsync( id )
FindAsync
method is used to asynchronously find an entity with the given primary key values.
// 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 ); } |
_context.Update( book );
await _context.SaveChangesAsync( );
Update
method marks an entity as modified in the database context so that changes will be saved to the database when SaveChangesAsync
is called.
using ..;
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 |