Full CRUD Project with Razor Pages
Advanced
30 min read
Lesson 8 of 8
Project Overview
Build a complete CRUD (Create, Read, Update, Delete) application for managing products.
1. Create the Model
// Models/Product.cs
public class Product
{
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; }
[Required]
[Range(0.01, 9999.99)]
public decimal Price { get; set; }
[StringLength(500)]
public string Description { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
public DateTime CreatedDate { get; set; }
public bool IsActive { get; set; }
}
2. Create DbContext
// Data/ApplicationDbContext.cs
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Product> Products { get; set; }
public DbSet<Category> Categories { get; set; }
}
3. Create the Index Page (Read)
// Pages/Products/Index.cshtml.cs
public class IndexModel : PageModel
{
private readonly ApplicationDbContext _context;
public IndexModel(ApplicationDbContext context)
{
_context = context;
}
public List<Product> Products { get; set; }
public async Task OnGetAsync()
{
Products = await _context.Products
.Include(p => p.Category)
.ToListAsync();
}
}
4. Create the Create Page
// Pages/Products/Create.cshtml.cs
public class CreateModel : PageModel
{
private readonly ApplicationDbContext _context;
public CreateModel(ApplicationDbContext context)
{
_context = context;
}
[BindProperty]
public Product Product { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
return Page();
Product.CreatedDate = DateTime.Now;
_context.Products.Add(Product);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
5. Create the Edit Page (Update)
// Pages/Products/Edit.cshtml.cs
public class EditModel : PageModel
{
private readonly ApplicationDbContext _context;
public EditModel(ApplicationDbContext context)
{
_context = context;
}
[BindProperty]
public Product Product { get; set; }
public async Task<IActionResult> OnGetAsync(int id)
{
Product = await _context.Products.FindAsync(id);
if (Product == null)
return NotFound();
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
return Page();
_context.Attach(Product).State = EntityState.Modified;
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
6. Create the Delete Page
// Pages/Products/Delete.cshtml.cs
public class DeleteModel : PageModel
{
private readonly ApplicationDbContext _context;
public DeleteModel(ApplicationDbContext context)
{
_context = context;
}
[BindProperty]
public Product Product { get; set; }
public async Task<IActionResult> OnGetAsync(int id)
{
Product = await _context.Products.FindAsync(id);
if (Product == null)
return NotFound();
return Page();
}
public async Task<IActionResult> OnPostAsync(int id)
{
Product = await _context.Products.FindAsync(id);
if (Product != null)
{
_context.Products.Remove(Product);
await _context.SaveChangesAsync();
}
return RedirectToPage("./Index");
}
}
7. Create the Views
// Pages/Products/Index.cshtml
@page
@model IndexModel
<h1>Products</h1>
<a asp-page="Create" class="btn btn-primary">Create New</a>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Category</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Products)
{
<tr>
<td>@item.Name</td>
<td>@item.Price.ToString("C")</td>
<td>@item.Category?.Name</td>
<td>
<a asp-page="Edit" asp-route-id="@item.Id">Edit</a>
<a asp-page="Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Key Takeaway
A full CRUD application demonstrates all essential Razor Pages concepts in a practical project.
Exercise
- Create a Product model with validation
- Implement all CRUD operations
- Add search and filtering
- Add pagination
- Implement user authentication