Recently, I've been working on a project where my project manager asked me to implement DataTables with insert, update, and delete operations using jQuery.
I also needed to reload the DataTable without refreshing the entire page. I successfully completed this task in our project, so I decided to share my experience with all developers so they can benefit from my approach.
If you are wokring on Razor pages based application then you can read this post
In our example, we are going to perform CRUD operations in ASP.NET Core using Entity Framework Core database-first approach. So, let's first set up Entity Framework in our project.
Step1:Create a new .NET Core Web Application project in Visual Studio.
Open Visual Studio and Mvc Web Application Project
Here's a step-by-step guide along with code to create a DbContext using Entity Framework Code First.:
Step 2: Install Entity Framework Core and the necessary database provider package. For example, if you're using SQL Server, you can install the packages using NuGet Package Manager Console:
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Tools
Make sure to use correct version based on your .Net core project. using System;
namespace DemoWebApp.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime CreatedAt { get; set; }
}
}
Step 4: Create a DbContext class that inherits from DbContext and defines a DbSet for each of your model classes. let's create a folder in the projetc named "DataBaseEntity".using DemoWebApp.Models;
using Microsoft.EntityFrameworkCore;
namespace DemoWebApp.DataBaseEntity
{
public class ProductDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=DESKTOP-MFLCOI2;Initial Catalog=DemoDb;User ID=sa;Password=adk@1234");
}
}
}
Replace connection string with the actual connection string to your SQL Server database. using DemoWebApp.DataBaseEntity;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<ProductDbContext>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Add-Migration InitialDb
After successfully running the command, it will create a folder in our project named 'Migrations'. You will be able to see it in the root directory.Step 7: Apply the migration to create the database,After running 'Update-Database', the migration will be applied to our database, creating the tables for us.
Update-Database
<script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
<link href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css" rel="stylesheet" />
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - DemoWebApp</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/DemoWebApp.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">DemoWebApp</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2024 - DemoWebApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
<link href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css" rel="stylesheet" />
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Step 9: Create a ProductController
using DemoWebApp.DataBaseEntity;
using DemoWebApp.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Composition.Convention;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace DemoWebApp.Controllers
{
public class ProductDTO
{
public List<Product> Data { get; set; }
}
public class ProductController : Controller
{
private readonly ProductDbContext _context;
public ProductController(ProductDbContext context)
{
_context = context;
}
public IActionResult Index()
{
return View();
}
// Action method to get all products
[HttpGet]
public IActionResult GetAllProducts()
{
var products = _context.Products.ToList();
return Json(new ProductDTO { Data=products });
}
// Action method to display the create form
public IActionResult Create()
{
return View();
}
// Action method to handle the form submission and create a new product
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Product product)
{
if (ModelState.IsValid)
{
product.CreatedAt = DateTime.Now;
_context.Products.Add(product);
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
return View(product);
}
// Action method to display the edit form for a specific product
public IActionResult Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var product = _context.Products.Find(id);
if (product == null)
{
return NotFound();
}
return View(product);
}
// Action method to handle the form submission and update an existing product
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(Product product)
{
if (ModelState.IsValid)
{
try
{
var productObj = _context.Products.Find(product.Id);
productObj.Name = product.Name;
productObj.Price = product.Price;
_context.Update(productObj);
_context.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(product.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(product);
}
private bool ProductExists(int id)
{
return _context.Products.Any(e => e.Id == id);
}
// Action method to delete a product
[HttpPost]
public IActionResult DeleteProduct(int id)
{
var product = _context.Products.Find(id);
if (product != null)
{
_context.Products.Remove(product);
_context.SaveChanges();
return Json(new { success = true });
}
return Json(new { success = false });
}
}
}
Step 10: So let's create views for performing operations. @{
ViewData["Title"] = "Product Management"; ;
Layout = "~/Views/Shared/_Layout.cshtml";
}
<a href="/Product/Create" class="btn btn-info">Add Product</a>
<table id="productTable" class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Price</th>
<th>Created At</th>
<th>Action</th>
</tr>
</thead>
<tbody></tbody>
</table>
@section scripts {
<script>
$(document).ready(function () {
$('#productTable').DataTable({
"ajax": {
"url": "/Product/GetAllProducts",
"type": "GET",
"datatype": "json"
},
"columns": [
{ "data": "id" },
{ "data": "name" },
{ "data": "price" },
{ "data": "createdAt" },
{
"data": null,
"render": function (data, type, row) {
return "<button class='btn btn-info' onclick='EditProduct(" + data.id + ")'>Edit</button> | <button class='btn btn-danger' onclick='DeleteProduct(" + data.id + ")'>Delete</button>";
}
}
]
});
});
// Function to delete a product
function DeleteProduct(id) {
if (confirm('Are you sure you want to delete this product?')) {
$.ajax({
type: "POST",
url: '/Product/DeleteProduct',
data: { id: id },
success: function (data) {
if (data.success) {
$('#productTable').DataTable().ajax.reload();
} else {
alert('Failed to delete product.');
}
}
});
}
}
// Function to edit a product
function EditProduct(id) {
window.location.href="/Product/Edit/"+id;
}
</script>
}
Create.cshtmlIn this Create view:@model DemoWebApp.Models.Product @{ ViewData["Title"] = "Create"; Layout = "~/Views/Shared/_Layout.cshtml"; } <form asp-action="Create"> <div class="form-group"> <label asp-for="Name" class="control-label"></label> <input asp-for="Name" class="form-control" /> <span asp-validation-for="Name" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Price" class="control-label"></label> <input asp-for="Price" class="form-control" /> <span asp-validation-for="Price" class="text-danger"></span> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-primary" /> </div> </form>
- We create a form that submits to the Create action of the Product controller. Inside the form, we have input fields for the Name and Price properties of the Product model.
- We include validation error messages for each input field using asp-validation-for.
- Finally, we have a submit button to create the product.
- We use the [ValidateAntiForgeryToken] attribute for security against cross-site request forgery attacks.
@model MvcCrudWithDataTable.Models.Product
@{
ViewData["Title"] = "Edit Product";
}
<h2>@ViewData["Title"]</h2>
<form asp-action="Edit">
<input type="hidden" asp-for="Id" />
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Price" class="control-label"></label>
<input asp-for="Price" class="form-control" />
<span asp-validation-for="Price" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
In this Edit view:
- We declare the model to be of type Product.
- We create a form that submits to the Edit action of the Product controller. We include a hidden input field for the Id property of the Product model so that the controller knows which product to update.
- Inside the form, we have input fields for the Name and Price properties of the Product model.
- We include validation error messages for each input field using asp-validation-for. Finally, we have a submit button to save the changes made to the product.
// Function to delete a product
function DeleteProduct(id) {
if (confirm('Are you sure you want to delete this product?')) {
$.ajax({
type: "POST",
url: '/Product/DeleteProduct',
data: { id: id },
success: function (data) {
if (data.success) {
$('#productTable').DataTable().ajax.reload();
} else {
alert('Failed to delete product.');
}
}
});
}
}
Read Similar Articles
- Upload and Display an Image in Gridview From Image Path in Database -C#
- How To Read .Txt File With Chinese characters In VBA?
- Create Stored Procedure with Output and Input parameters in SQL
- What is Sql Joins? With Realtime Examples
- How Send An HTTP POST Request To A Server From Excel Using VBA?
- ASP.NET Core SignalR - How to Join & Remove a Group and Send To a Group From Client
- [Solved]-"Spring Boot, typeerror: failed to execute 'fetch' on 'window': request with get/head method cannot have body."