SupermarketWEB follows the ASP.NET Core Razor Pages architecture with a clean separation of concerns. This guide explains the purpose of each directory and key files.
Directory Overview
SupermarketWEB/
├── Data/ # Database context and data access
├── Models/ # Entity and data models
├── Pages/ # Razor Pages (views and page models)
│ ├── Account/ # Authentication pages
│ ├── Categories/ # Category CRUD operations
│ ├── Customers/ # Customer management
│ ├── PayModes/ # Payment modes management
│ ├── Products/ # Product inventory management
│ └── Shared/ # Shared layouts and partials
├── Properties/ # Project properties and launch settings
├── wwwroot/ # Static files (CSS, JS, images)
├── Program.cs # Application entry point and configuration
├── SupermarketWEB.csproj # Project file and dependencies
└── appsettings.json # Application configuration
Core Directories
Data/
Contains the Entity Framework Core database context.
Data/
└── SupermarketContext.cs # DbContext with entity configurations
The SupermarketContext class manages database connections and entity sets:
Data/SupermarketContext.cs
public class SupermarketContext : DbContext
{
public SupermarketContext ( DbContextOptions options ) : base ( options )
{
}
public DbSet < Product > Products { get ; set ; }
public DbSet < Category > Categories { get ; set ; }
public DbSet < Customer > Customers { get ; set ; }
public DbSet < PayMode > PayModes { get ; set ; }
public DbSet < User > Users { get ; set ; }
}
The DbContext is injected into page models via dependency injection, configured in Program.cs.
Models/
Contains entity classes that represent database tables and business domain objects.
Models/
├── Category.cs # Product categories
├── Customer.cs # Customer information
├── PayMode.cs # Payment methods
├── Product.cs # Product inventory items
└── User.cs # Application users
Example Model: Product
using System . ComponentModel . DataAnnotations . Schema ;
namespace SupermarketWEB . Models
{
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 ; }
}
}
Models use data annotations to:
Define database column types (e.g., decimal(6,2) for precise currency)
Establish relationships between entities
Mark nullable properties
Navigation properties like Category enable Entity Framework to load related data and establish foreign key relationships.
Pages/
Contains all Razor Pages organized by feature. Each page consists of two files:
.cshtml - The view (HTML + Razor syntax)
.cshtml.cs - The page model (C# logic)
Pages/
├── Account/ # User authentication
│ ├── Login.cshtml
│ ├── Login.cshtml.cs
│ ├── Logout.cshtml
│ ├── Logout.cshtml.cs
│ ├── Register.cshtml
│ └── Register.cshtml.cs
├── Categories/ # Category management
│ ├── Index.cshtml # List categories
│ ├── Create.cshtml # Create new category
│ ├── Edit.cshtml # Edit category
│ └── Delete.cshtml # Delete category
├── Customers/ # Customer management (CRUD)
├── PayModes/ # Payment modes (CRUD)
├── Products/ # Product management (CRUD)
├── Shared/ # Shared components
│ ├── _Layout.cshtml # Main layout template
│ ├── _LoginStatusPartial.cshtml
│ └── _ValidationScriptsPartial.cshtml
├── Index.cshtml # Home page
├── Privacy.cshtml # Privacy policy page
├── _ViewImports.cshtml # Global using directives
└── _ViewStart.cshtml # Default layout configuration
Feature-based Organization
Each feature (Categories, Products, Customers, PayModes) follows a consistent CRUD pattern:
Index - List all items
Create - Add new item
Edit - Modify existing item
Delete - Remove item
This consistent structure makes the application predictable and easy to maintain.
Shared Components
The Shared/ folder contains reusable UI components:
_Layout.cshtml - Main application template with navigation:
Pages/Shared/_Layout.cshtml (excerpt)
<nav class="navbar navbar-expand-lg bg-body-tertiary rounded">
<div class="container-fluid">
<a class="navbar-brand" asp-page="/Index">
<img src="Images\Icons\Supermarket.ico" width="20" height="20" alt="Carrito">
SupermarketWeb
</a>
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" asp-page="/Products/Index">Product</a>
</li>
<li class="nav-item">
<a class="nav-link active" asp-page="/Categories/Index">Category</a>
</li>
<!-- More nav items -->
</ul>
<partial name="_loginStatusPartial" />
</div>
</nav>
_LoginStatusPartial.cshtml - Authentication status display:
Pages/Shared/_LoginStatusPartial.cshtml
@if(User.Identity.IsAuthenticated)
{
<form method="post" class="form-inline" asp-page="/Account/Logout">
Welcome @User.Identity.Name
<button type="submit" class="m-lg-2 btn btn-link">Logout</button>
</form>
}
else
{
<a class="btn btn-l" asp-page="/Account/Login">Login</a>
}
wwwroot/
Static files served directly to the browser.
wwwroot/
├── css/ # Stylesheets
│ └── site.css # Custom styles
├── js/ # JavaScript files
│ └── site.js # Custom scripts
├── lib/ # Client-side libraries
│ ├── bootstrap/ # Bootstrap framework
│ └── jquery/ # jQuery library
├── Images/ # Application images
│ └── Icons/ # Icon files
└── favicon.ico # Site favicon
Files in wwwroot are publicly accessible. Reference them in views using the ~ prefix: ~/css/site.css
Properties/
Contains project launch settings and configuration.
Properties/
└── launchSettings.json # Development server configuration
Key Files
Program.cs
Application entry point that configures services and middleware:
using Microsoft . EntityFrameworkCore ;
using SupermarketWEB . Data ;
namespace SupermarketWEB
{
public class Program
{
public static void Main ( string [] args )
{
var builder = WebApplication . CreateBuilder ( args );
// Add services to the container
builder . Services . AddRazorPages ();
// Configure Entity Framework with SQL Server
builder . Services . AddDbContext < SupermarketContext >( options =>
options . UseSqlServer ( builder . Configuration . GetConnectionString ( "SupermarketDB" ))
);
// Configure cookie authentication
builder . Services . AddAuthentication (). AddCookie ( "MyCookieAuth" , option =>
{
option . Cookie . Name = "MyCookieAuth" ;
option . LoginPath = "/Account/Login" ;
});
var app = builder . Build ();
// Configure the HTTP request pipeline
if ( ! app . Environment . IsDevelopment ())
{
app . UseExceptionHandler ( "/Error" );
app . UseHsts ();
}
app . UseHttpsRedirection ();
app . UseStaticFiles ();
app . UseRouting ();
app . UseAuthorization ();
app . MapRazorPages ();
app . Run ();
}
}
}
Key responsibilities:
Service Registration - Configure dependency injection
Database Context - Register Entity Framework DbContext
Authentication - Setup cookie-based authentication
Middleware Pipeline - Configure request processing order
The middleware order in Program.cs is critical. Always configure in this sequence: Exception handling → HTTPS → Static files → Routing → Authorization → Endpoints.
appsettings.json
Application configuration including connection strings and logging:
{
"Logging" : {
"LogLevel" : {
"Default" : "Information" ,
"Microsoft.AspNetCore" : "Warning"
}
},
"ConnectionStrings" : {
"SupermarketDB" : "Data Source=(localdb) \\ MSSQLLocalDB;Initial Catalog=SupermarketEF;Integrated Security=True;..."
},
"AllowedHosts" : "*"
}
Use appsettings.Development.json for development-specific settings. It automatically overrides appsettings.json values during development.
SupermarketWEB.csproj
Project file defining target framework and NuGet package dependencies:
< Project Sdk = "Microsoft.NET.Sdk.Web" >
< PropertyGroup >
< TargetFramework > net8.0 </ TargetFramework >
< Nullable > enable </ Nullable >
< ImplicitUsings > enable </ ImplicitUsings >
</ PropertyGroup >
< ItemGroup >
< PackageReference Include = "Microsoft.EntityFrameworkCore" Version = "8.0.10" />
< PackageReference Include = "Microsoft.EntityFrameworkCore.SqlServer" Version = "8.0.10" />
</ ItemGroup >
</ Project >
Dependencies:
Microsoft.EntityFrameworkCore - EF Core runtime
Microsoft.EntityFrameworkCore.SqlServer - SQL Server provider
ASP.NET Core Razor Pages Architecture
SupermarketWEB follows the Razor Pages pattern:
Request → Routing → Page Model (C#) → View (Razor) → Response
Request Arrives
User navigates to /Categories/Index
Routing
ASP.NET Core maps URL to Pages/Categories/Index.cshtml
Page Model Execution
IndexModel.OnGetAsync() loads data from database
View Rendering
Razor template generates HTML with data
Response
HTML sent to browser
Conventions
Razor Pages uses convention-based routing:
URL Maps to File /Pages/Index.cshtml/CategoriesPages/Categories/Index.cshtml/Categories/CreatePages/Categories/Create.cshtml/Products/Edit/5Pages/Products/Edit.cshtml (with id=5)
The @page directive at the top of each .cshtml file enables Razor Pages routing for that file.
Data Flow
Understanding how data moves through the application:
User Action - User clicks “Categories” in navigation
Routing - Request routed to Pages/Categories/Index.cshtml.cs
Database Query - Page model queries SupermarketContext.Categories
Data Binding - Results stored in Categories property
View Rendering - Razor template iterates over Model.Categories
HTML Output - Generated HTML sent to browser
Example from Categories Index page model:
Pages/Categories/Index.cshtml.cs
[ Authorize ]
public class IndexModel : PageModel
{
private readonly SupermarketContext _context ;
public IndexModel ( SupermarketContext context )
{
_context = context ;
}
public IList < Category > Categories { get ; set ; } = default ! ;
public async Task OnGetAsync ()
{
if ( _context . Categories != null )
{
Categories = await _context . Categories . ToListAsync ();
}
}
}
Next Steps