Razor Page CRUD In ASP.NET 6 With JQuery AJAX

Last modified: April 10, 2022

1. Create a Razor Page .NET 6 application

project project project project

2. Create a Model and DBContext

  • Create a folder called Models
  • Create a folder called Data
  • In the Models, create a class called Customer
  • In the Data, create a class called CustomerDBContext
Nuget Packages

Install the following packages. For Demo, we are using InMemory but for your production, you need to select SQL Server or other NuGet Package

project project

public class Customer { public int Id { get; set; } public string Name { get; set; } public string Email { get; set; } public string MobileNumber { get; set; } }
public class CustomerDBContext : DbContext { public CustomerDBContext(DbContextOptions<CustomerDBContext> options) : base(options) { } public DbSet<Customer> Customer { get; set; } }

3. Interfaces & Repository

We create Interfaces folder and create these Interfaces

public interface IGenericRepository<T> where T : class { Task<T?> GetById(int id); Task<IEnumerable<T>> GetAll(); Task<bool> Add(T entity); Task<bool> Remove(int id); T Update(T entity); }
public interface ICustomerRepository : IGenericRepository<Customer> { }
public interface IUnitOfWork : IDisposable { ICustomerRepository Customer { get; } Task<int> CompletedAsync(); }

Create Repository folder

public class GenericRepository<T> : IGenericRepository<T> where T : class { protected CustomerDBContext _context; protected DbSet<T> dbSet; public GenericRepository( CustomerDBContext context) { _context = context; dbSet = _context.Set<T>(); } public async Task<bool> Add(T entity) { await dbSet.AddAsync(entity); return true; } public async Task<IEnumerable<T>> GetAll() { return await dbSet.ToListAsync(); } public async Task<T?> GetById(int id) { return await dbSet.FindAsync(id); } public async Task<bool> Remove(int id) { var t = await dbSet.FindAsync(id); if (t != null) { dbSet.Remove(t); return true; } else return false; } public T Update(T entity) { _context.Entry(entity).State = EntityState.Modified; return entity; } }
public class CustomerRepository : GenericRepository<Customer>, ICustomerRepository { public CustomerRepository(CustomerDBContext context) : base(context) { } }
public class UnitOfWork : IUnitOfWork { private readonly CustomerDBContext _context; public ICustomerRepository Customer { get; set; } public UnitOfWork( CustomerDBContext context ) { _context = context; Customer = new CustomerRepository(_context); } public async Task<int> CompletedAsync() { return await _context.SaveChangesAsync(); } public void Dispose() { _context.Dispose(); } }

4. Program.cs

Add the below DI

builder.Services.AddTransient<IUnitOfWork, UnitOfWork>();

5. Pages

public class IndexModel : PageModel { private readonly ILogger<IndexModel> _logger; private readonly IUnitOfWork _unitOfWork; public IndexModel(ILogger<IndexModel> logger, IUnitOfWork unitOfWork) { _logger = logger; _unitOfWork = unitOfWork; } public async Task<JsonResult> OnGetRecord() { var customers = await _unitOfWork.Customer.GetAll(); return new JsonResult(customers); } public async Task<JsonResult> OnPostAdd(Customer customer) { if (customer.Id > 0) { var cus = _unitOfWork.Customer.Update(customer); await _unitOfWork.CompletedAsync(); return new JsonResult(cus); } else { await _unitOfWork.Customer.Add(customer); await _unitOfWork.CompletedAsync(); } return new JsonResult("Add Successful"); } public async Task<JsonResult> OnPostDelete(string id) { await _unitOfWork.Customer.Remove(int.Parse(id)); await _unitOfWork.CompletedAsync(); return new JsonResult("Delete Successful"); } public async Task<JsonResult> OnGetById(string Id) { var customer = await _unitOfWork.Customer.GetById(int.Parse(Id)); return new JsonResult(customer); } }
Layout page

replace or add following JavaScripts

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
Modal used for adding and updating customer record. It is bootstrap modal
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#customerModel"> Add Customer </button> <!-- Modal --> <div class="modal fade" id="customerModel" tabindex="-1" role="dialog" aria-labelledby="customerModelTitle" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLongTitle">Modal title</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">&times;</span> </button> </div> <div class="modal-body"> <form> <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" id="name" name="name" aria-describedby="nameHelp" placeholder="Enter your name"> <label for="email">Email address</label> <input type="email" class="form-control" id="email" name="email" aria-describedby="emailHelp" placeholder="Enter email"> <label for="mobile">Mobile Number</label> <input type="text" class="form-control" id="mobileNumber" name="MobileNumber" aria-describedby="mobileHelp" placeholder="Enter your mobile number"> <input type="hidden" id="id" name="id" /> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <button type="button" id="btnAdd" class="btn btn-primary">Save changes</button> </div> </div> </div> </div>
$("#btnAdd").click(function(){ $.ajax({ type: "POST", url: "/Index?handler=Add", data: $('form').serialize(), contentType: 'application/x-www-form-urlencoded', dataType: "json", headers: { "RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val() }, success: function (msg) { if ($('#btnAdd').hasClass('btn-update')) { $('table#CustomerTable tr#' + msg.id).find("td").eq(1).html(msg.name); $('table#CustomerTable tr#' + msg.id).find("td").eq(2).html(msg.email); $('table#CustomerTable tr#' + msg.id).find("td").eq(3).html(msg.mobileNumber); $("#btnAdd").removeClass('btn-update'); } else { loadCustomerRecords(); //refresh the table } $('#customerModel').modal('hide'); //hide the modal } });
Table to display list of Customer records
<table id="CustomerTable" class="table table-striped table-bordered table-hover"> <thead> <tr> <th>Name</th> <th>Email</th> <th>Mobile Number</th> <th></th> <th></th> </tr> </thead> <tbody> </tbody> </table>
function loadCustomerRecords() { $.ajax({ type: "GET", url: "/Index?handler=Record", contentType: 'application/x-www-form-urlencoded', dataType: "json", headers: { "RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val() }, success: function (msg) { DrawTable(msg); } }); }
JavaScript to create a table from JSON response
function DrawTable(response) { $.each(response, function(i, item) { var $tr = $('<tr id="'+item.id+'">').append( $('<td>').text(item.name), $('<td>').text(item.email), $('<td>').text(item.mobileNumber), $('<td>').html('<button type="button" args="'+ item.id +'" class="btn-edit btn btn-success">Edit</button>'), $('<td>').html('<button type="button" args="'+ item.id +'" class="btn-delete btn btn-danger">Delete</button>') ).appendTo('#CustomerTable'); }); }
Edit and Delete JavaScript functions
$(document).on('click', '.btn-edit', function(){ var id = $(this).attr('args'); $.ajax({ type: "GET", url: "/Index?handler=ById", data: {"id": id}, contentType: 'application/x-www-form-urlencoded', dataType: "json", headers: { "RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val() }, success: function (msg) { $("#name").val(msg.name); $("#email").val(msg.email); $("#mobileNumber").val(msg.mobileNumber); $("#id").val(msg.id); $("#btnAdd").addClass("btn-update"); //add the btn-update class to modal save button so that we can make diferrent between add or update action $('#customerModel').modal('show'); } }); }); $(document).on('click', '.btn-delete', function(){ var id = $(this).attr('args'); $.ajax({ type: "POST", url: "/Index?handler=Delete", data: {"id": id}, contentType: 'application/x-www-form-urlencoded', dataType: "json", headers: { "RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val() }, success: function (msg) { $('table#CustomerTable tr#'+ id).remove(); } }); });
  1. Test the application

test test test

You can find the source code here