Skip to main content

Overview

The Product Management module provides full Create, Read, Update, and Delete (CRUD) functionality for managing supermarket inventory. Products are linked to categories and include pricing and stock information.

Product Model

The Product model (Models/Product.cs:5-15) defines the structure for product data:
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }

    [Column(TypeName = "decimal(6,2)")]
    public decimal Price { get; set; }
    public int Stock { get; set; }
    public int CategoryId { get; set; }
    public Category? Category { get; set; }
}

Properties

PropertyTypeAttributesDescription
Idint-Unique identifier
Namestring-Product name
Pricedecimaldecimal(6,2)Product price (up to 9999.99)
Stockint-Available quantity in inventory
CategoryIdintForeign KeyReference to product category
CategoryCategory?NavigationRelated category object
The Price property uses the [Column(TypeName = "decimal(6,2)")] attribute to ensure precise monetary values with 2 decimal places in the database.

CRUD Operations

Viewing All Products

The Index page (Pages/Products/Index.cshtml.cs:22-28) retrieves and displays all products:
public async Task OnGetAsync()
{
    if (_context.Products != null)
    {
        Products = await _context.Products.ToListAsync();
    }
}
The page uses Entity Framework Core’s ToListAsync() to asynchronously fetch all products from the database.

Category Relationship

Products are linked to categories through a foreign key relationship:
public int CategoryId { get; set; }
public Category? Category { get; set; }
This allows products to be organized and filtered by category. The Category navigation property enables loading related category information when needed.

Authorization

All product management pages are protected with the [Authorize] attribute:
[Authorize]
public class IndexModel : PageModel
{
    // Implementation
}
Only authenticated users can access product management features. Unauthenticated requests are redirected to /Account/Login.

Database Context

Products are managed through the SupermarketContext (Data/SupermarketContext.cs:13):
public DbSet<Product> Products { get; set; }

Page Structure

The product management module consists of four Razor Pages:

Index

/Pages/Products/Index.cshtmlDisplays all products in a list or table format

Create

/Pages/Products/Create.cshtmlForm for adding new products

Edit

/Pages/Products/Edit.cshtmlForm for updating existing products

Delete

/Pages/Products/Delete.cshtmlConfirmation page for product deletion

Common Patterns

Model Binding

All CRUD operations use the [BindProperty] attribute for automatic form binding:
[BindProperty]
public Product Products { get; set; } = default!;

Validation

ModelState validation ensures data integrity:
if (!ModelState.IsValid)
{
    return Page();
}

Async Operations

All database operations are asynchronous for better performance:
await _context.Products.ToListAsync();
await _context.SaveChangesAsync();

Best Practices

Always validate user input using ModelState before saving to the database. The Product model should include appropriate data annotations for validation.
The edit operation includes concurrency exception handling to prevent data conflicts. Consider adding try-catch blocks for other operations as well.
The decimal(6,2) type ensures accurate price calculations without floating-point errors. Always use decimal types for monetary values.

Build docs developers (and LLMs) love