In this post, we will learn how to perform CRUD operation in ASP.Net Core using jQuery Ajax and Bootstrap modal popup. So the question is why we want to perform CRUD using modal popups- the answer is sometimes we want CRUD on a single page or same page only. So lets start CRUD with bootstrap modal popups. Below are steps with detail code, you can also download the code in case you want to see demo.
In this example I am using SqlServer, jQuery Ajax, ASP.Net Core RazorPages. You can use ASP.Net Core MVC or jQuery Modal in similar way.
Follow the below steps to achieve same:-
Step-1: Create a SQL Table lets say "Products"
CREATE TABLE [dbo].[Products](
[ProductId] [bigint] IDENTITY(1,1) PRIMARY KEY,
[ProductName] [nvarchar](100) NOT NULL,
[Category] [nvarchar](100) NULL,
[Description] [nvarchar](1000) NULL,
[UnitPrice] [decimal](18, 2) NOT NULL
)
Step-2: Create a ASP.Net Core Project (I am creating project with template to get jQuery & Bootstrap files in project automatically. We can add these files manually also.)
Step-3: Add a Model Class for Products as shown below
public class Products
{
[Key]
[Required]
public long ProductId { get; set; }
[Display(Name = "Product Name")]
[Required, StringLength(100)]
public string ProductName { get; set; }
[Display(Name = "Category")]
[Required, StringLength(100)]
public string Category { get; set; }
[Display(Name = "Description")]
public string Description { get; set; }
[Display(Name = "Unit Price")]
[Required, RegularExpression(@"\d+(\.\d{1,2})?", ErrorMessage = "Invalid UnitPrice")]
public decimal UnitPrice { get; set; }
}
Step-4: Add a DBContext Class as shown below
public class AppDBContext : DbContext
{
public AppDBContext(DbContextOptions<AppDBContext> options)
: base(options)
{
}
public DbSet<Products> Products { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
}
}
Step-5: Register DBContext Class in Startup.cs ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
var connection = Configuration.GetConnectionString("ConStr");
services.AddDbContext<AppDBContext>(options=>options.UseSqlServer(connection));
services.AddRazorPages();
}
Step-6: Create a RazorPage "ManageProducts" with below Markups
@page
@model ManageProductsModel
@{
ViewData["Title"] = "Manage Products";
}
<!-- Start: List Model-->
<div id="listModel">
<div class="row">
<div class="col-md-12">
@if (!string.IsNullOrEmpty(Model.Message))
{
<div class="alert alert-primary">
@Model.Message
</div>
}
<div class="card">
<div class="box-header card-header">
<button type="button" class="btn btn-primary float-left pull-left" data-toggle="modal" data-target="#addProductModal">
Add Product
</button>
<form method="post" asp-page="ManageProducts" asp-page-handler="Search">
<input type="submit" name="btnSearch" id="btnSearch" class="btn btn-primary float-right pull-right" value="Search" />
<input type="text" name="searchTerm" id="searchTerm" class="form-control float-right pull-right" style="width:180px;margin-right:10px;" />
</form>
</div>
<div class="box-body card-body">
<table id="manageProduct" class="table table-striped">
<thead>
<tr>
<th scope="col">
@Html.DisplayNameFor(model => model.ProductList[0].ProductName)
</th>
<th scope="col">
@Html.DisplayNameFor(model => model.ProductList[0].Category)
</th>
<th scope="col">
@Html.DisplayNameFor(model => model.ProductList[0].Description)
</th>
<th scope="col">
@Html.DisplayNameFor(model => model.ProductList[0].UnitPrice)
</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.ProductList)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.ProductName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Category)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
@Html.DisplayFor(modelItem => item.UnitPrice)
</td>
<td>
<a href="#editProductModal" class="edit" data-toggle="modal">Edit</a> |
<a href="#viewProductModal" class="view" data-toggle="modal">View</a> |
<a href="#deleteProductModal" class="delete" data-toggle="modal">Delete</a>
<input type="hidden" name="productID" id="productID" asp-for="@item.ProductId" />
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- End: List Model-->
<!-- Start: Add Modal-->
<div class="modal fade" id="addProductModal">
<div class="modal-dialog">
<div class="modal-content">
<form method="post" asp-page="ManageProducts" asp-page-handler="AddProduct">
<div class="modal-header">
<h3 class="modal-title">Add New Product</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Product.ProductName" class="control-label"></label>
<input asp-for="Product.ProductName" class="form-control" />
<span asp-validation-for="Product.ProductName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Product.Category" class="control-label"></label>
<input asp-for="Product.Category" class="form-control" />
<span asp-validation-for="Product.Category" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Product.Description" class="control-label"></label>
<input asp-for="Product.Description" class="form-control" />
<span asp-validation-for="Product.Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Product.UnitPrice" class="control-label"></label>
<input asp-for="Product.UnitPrice" class="form-control" />
<span asp-validation-for="Product.UnitPrice" class="text-danger"></span>
</div>
</div>
<div class="modal-footer">
<input type="submit" value="Create" class="btn btn-success" />
<input type="button" value="Cancel" class="btn btn-primary" data-dismiss="modal" />
</div>
</form>
</div>
</div>
</div>
<!-- End: Add Modal-->
<!-- Start: Edit Modal-->
<div class="modal fade" id="editProductModal">
<div class="modal-dialog">
<div class="modal-content">
<form method="post" asp-page="ManageProducts" asp-page-handler="UpdateProduct">
<div class="modal-header">
<h3 class="modal-title">Update Product</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Product.ProductId" />
<div class="form-group">
<label asp-for="Product.ProductName" class="control-label"></label>
<input asp-for="Product.ProductName" class="form-control" />
<span asp-validation-for="Product.ProductName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Product.Category" class="control-label"></label>
<input asp-for="Product.Category" class="form-control" />
<span asp-validation-for="Product.Category" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Product.Description" class="control-label"></label>
<input asp-for="Product.Description" class="form-control" />
<span asp-validation-for="Product.Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Product.UnitPrice" class="control-label"></label>
<input asp-for="Product.UnitPrice" class="form-control" />
<span asp-validation-for="Product.UnitPrice" class="text-danger"></span>
</div>
</div>
<div class="modal-footer">
<input type="submit" value="Update" class="btn btn-success" />
<input type="button" value="Cancel" class="btn btn-primary" data-dismiss="modal" />
</div>
</form>
</div>
</div>
</div>
<!-- End: Edit Modal-->
<!-- Start: View Modal-->
<div class="modal fade" id="viewProductModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">View Product</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="box box-primary">
<dl class="row">
<dt class="col-sm-6">
@Html.DisplayNameFor(model => model.Product.ProductName)
</dt>
<dd class="col-sm-6" id="Product_ProductName">
</dd>
<dt class="col-sm-6">
@Html.DisplayNameFor(model => model.Product.Category)
</dt>
<dd class="col-sm-6" id="Product_Category">
</dd>
<dt class="col-sm-6">
@Html.DisplayNameFor(model => model.Product.Description)
</dt>
<dd class="col-sm-6" id="Product_Description">
</dd>
<dt class="col-sm-6">
@Html.DisplayNameFor(model => model.Product.UnitPrice)
</dt>
<dd class="col-sm-6" id="Product_UnitPrice">
</dd>
</dl>
</div>
</div>
<div class="modal-footer">
<input type="button" value="Cancel" class="btn btn-primary" data-dismiss="modal" />
</div>
</div>
</div>
</div>
<!-- End: View Modal-->
<!-- Start: Delete Modal-->
<div class="modal fade" id="deleteProductModal">
<div class="modal-dialog">
<div class="modal-content">
<form method="post" asp-page="ManageProducts" asp-page-handler="DeleteProduct">
<div class="modal-header">
<h3 class="modal-title">Delete Product</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete?</p>
<input type="hidden" name="productID" id="productID" />
</div>
<div class="modal-footer">
<input type="submit" value="Yes" class="btn btn-success" />
<input type="button" value="Cancel" class="btn btn-primary" data-dismiss="modal" />
</div>
</form>
</div>
</div>
</div>
<!-- End: Delete Modal-->
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
$(document).ready(function () {
$("table#manageProduct .delete").click(function () {
var productID = $(this).parent().find("#productID").val();
$("#deleteProductModal").find("#productID").val(productID);
});
$("table#manageProduct .edit").click(function () {
var productID = $(this).parent().find("#productID").val();
$("#editProductModal").find("#Product_ProductId").val(productID);
GetEditProductDetails(productID);
});
$("table#manageProduct .view").click(function () {
var productID = $(this).parent().find("#productID").val();
$("#viewProductModal").find("#Product_ProductId").val(productID);
GetViewProductDetails(productID);
});
});
function GetEditProductDetails(productID) {
$.ajax({
url: "@Url.Page("/ManageProducts","AjaxProductDetail")",
typr: "GET",
data: { "productID": "" + productID + "" },
contentType: "application/json;charset=UTF-8",
dataType: "json",
success: function (response) {
//alert(response);
$('#editProductModal #Product_ProductName').val(response.productName);
$('#editProductModal #Product_Category').val(response.category);
$('#editProductModal #Product_Description').val(response.description);
$('#editProductModal #Product_UnitPrice').val(response.unitPrice);
},
error: function (response) {
alert(response.responseText);
$('#editProductModal #Product_ProductName').val("");
$('#editProductModal #Product_Category').val("");
$('#editProductModal #Product_Description').val("");
$('#editProductModal #Product_UnitPrice').val("");
}
});
return false;
}
function GetViewProductDetails(productID) {
$.ajax({
url: "@Url.Page("/ManageProducts","AjaxProductDetail")",
typr: "GET",
data: { "productID": "" + productID + "" },
contentType: "application/json;charset=UTF-8",
dataType: "json",
success: function (response) {
//alert(response);
$('#viewProductModal #Product_ProductName').text(response.productName);
$('#viewProductModal #Product_Category').text(response.category);
$('#viewProductModal #Product_Description').text(response.description);
$('#viewProductModal #Product_UnitPrice').text(response.unitPrice);
},
error: function (response) {
alert(response.responseText);
$('#viewProductModal #Product_ProductName').text("");
$('#viewProductModal #Product_Category').text("");
$('#viewProductModal #Product_Description').text("");
$('#viewProductModal #Product_UnitPrice').text("");
}
});
return false;
}
</script>
}
Step-7: Implement CRUD in Razor PageModel (or in Controller in case of MVC)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using MyCoreDemo.Data;
namespace MyCoreDemo.Pages
{
public class ManageProductsModel : PageModel
{
AppDBContext _context;
public ManageProductsModel(AppDBContext context)
{
_context = context;
}
public List<Products> ProductList { get; set; }
[BindProperty(SupportsGet = true)]
public Products Product { get; set; }
[BindProperty(SupportsGet = true)]
public string SearchTerm { get; set; }
[TempData]
public string Message { get; set; }
public void OnGet()
{
ProductList = _context.Products.ToList();
}
public void OnPostSearch()
{
if (!string.IsNullOrEmpty(SearchTerm))
{
ProductList = _context.Products.Where(p => p.ProductName.Contains(SearchTerm)).ToList();
}
else
{
ProductList = _context.Products.ToList();
}
}
public IActionResult OnPostAddProduct()
{
if (!ModelState.IsValid)
{
return Page();
}
//
var existProduct = _context.Products.FirstOrDefault(e => e.ProductName == Product.ProductName && e.ProductId != Product.ProductId);
if (existProduct != null)
{
Message = "Product " + Product.ProductName + " already exist";
return RedirectToPage("/ManageProducts");
}
else
{
_context.Products.Add(Product);
_context.SaveChanges();
}
//
if (Product == null)
{
return RedirectToPage("Error");
}
Message = "Product " + Product.ProductName + " added successfully";
return RedirectToPage("/ManageProducts");
}
public IActionResult OnGetAjaxProductDetail(int productID)
{
if (productID == 0)
{
return RedirectToPage("Error");
}
Product = _context.Products.First(p => p.ProductId == productID);
if (Product == null)
{
return RedirectToPage("Error");
}
return new JsonResult(Product);
}
// Just for reference
public void OnGetProductDetail(int productID)
{
Product = _context.Products.First(p => p.ProductId == productID);
}
public IActionResult OnPostUpdateProduct()
{
if (!ModelState.IsValid)
{
return Page();
}
//
var existProduct = _context.Products.FirstOrDefault(e => e.ProductName == Product.ProductName && e.ProductId != Product.ProductId);
if (existProduct != null)
{
Message = "Product " + Product.ProductName + " already exist";
return RedirectToPage("/ManageProducts");
}
else
{
_context.Products.Attach(Product).State = EntityState.Modified;
_context.SaveChanges();
}
//
if (Product == null)
{
return RedirectToPage("Error");
}
Message = "Product " + Product.ProductName + " updated successfully";
return RedirectToPage("/ManageProducts");
}
public IActionResult OnPostDeleteProduct(int productID)
{
if (productID == 0)
{
return RedirectToPage("Error");
}
var Product = _context.Products.First(p => p.ProductId == productID);
_context.Products.Remove(Product);
_context.SaveChanges();
if (Product == null)
{
return RedirectToPage("Error");
}
Message = "Product " + Product.ProductName + " deleted successfully";
return RedirectToPage("/ManageProducts");
}
}
}
Step-8: Run the Project
Click here to download the project
Thats it !!