MVC Controllers: BooksController.cs (Cont.)

 // 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 ]
The attribute is used to indicate that a particular action method in a controller should only respond to HTTP POST requests.

[ ValidateAntiForgeryToken ]
The 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" )..;
Model binding automates the process of retrieving data that comes from HTTP requests. The model binding system:

  1. Retrieves data from various sources such as route data, form fields, and query strings.
  2. Provides the data to controllers and Razor pages in method parameters and public properties.
  3. Converts string data to .NET types.
  4. Updates properties of complex types.

The attribute is used to control which properties of a model are included or excluded during model binding.

ModelState.IsValid;
The 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 method, which allows you to asynchronously save changes made to the database context.

RedirectToAction( nameof( Index ) )
The method redirects to the specified action using the action name. The operator is used to obtain the name of a variable, type, or member as a string.
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 );
     }
   }
 }




      “Why do they lock gas station bathrooms?    
      Are they afraid someone will clean them?”    
      — George Carlin