ASP.NET Web Forms (C# 5) e-commerce demo • Admin + Account • SQL Server
Root →
/serena
- Overview
- Tech Stack
- Folder Structure
- Quick Start (No Login)
- Migrations
- Seeder (Sample Data)
- Key Features
- Reports & Printing
- Configuration
- Troubleshooting
- Security Checklist
Serena is a compact Web Forms store: catalog, cart/checkout (Account), and an Admin panel for products, categories, members, orders, feedbacks, payment methods, and reports.
SQL Server backs the data; ADO.NET with a tiny Db helper handles queries.
- .NET Framework: 4.5+ (C# 5)
- ASP.NET Web Forms with master pages (
MasterPages/Admin.master,MasterPages/Site.master) - SQL Server / LocalDB • ADO.NET (
App_Code/Data/Db.cs) - Bootstrap-style UI via site CSS
/Account/ # Login/Register/Profile/Orders/Checkout
/Admin/ # Dashboard, Products, Categories, Members, Orders, OrderView, Feedbacks, PaymentMethods, Reports
/Admin/ReportProduct.aspx # Printable Product Stock Report
/Admin/ReportOrder.aspx # Printable Delivered Orders Revenue Report
/App_Code/Data/Db.cs # DB helper
/App_Code/Data/Migrator.cs # Migration runner (tracks dbo.schema_migrations)
/App_Data/Serena.mdf # LocalDB (optional)
Assets/images/products/ # Uploaded product images
MasterPages/ # Admin.master, Site.master
Setup.aspx # Public first-run page (migrate + seed, protected by SetupKey)
Web.config
Global.asax
Error.aspx
First-run setup requires no admin login. Use Setup.aspx with a one-time key.
- Configure DB in
Web.config:
<connectionStrings>
<add name="DefaultConnection"
connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Serena.mdf;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>- Add a SetupKey (change the value):
<appSettings>
<add key="SetupKey" value="9C4F9E3B-7AD1-4E6D-AD13-6B9B1DB6F5E8" />
</appSettings>- Run setup (no login):
http://localhost:<port>/Setup.aspx?k=9C4F9E3B-7AD1-4E6D-AD13-6B9B1DB6F5E8
Click Run Migrations then Seed Sample Data (or Run Both).
- Secure/Remove
Setup.aspxafter initializing (rotate or delete the key).
Migrations are code-driven via App_Code/Data/Migrator.cs. They create all tables, constraints, and helpful indexes and record the applied version in dbo.schema_migrations. Re-running is safe (guards check existence).
Tables
admins,members,member_addresses,categories,products,payment_methodsorders,order_items,order_addresses,order_logsfeedbacks
Indexes
UQ_admins_username,UQ_members_username,UQ_members_email,UQ_payment_methods_name,UQ_orders_order_codeIX_orders_status_date(status, order_date)
Constraints
- FKs across products/categories, orders/members, items/orders/products, addresses/orders, logs/(orders, admins)
- Payment method CHECK:
name ∈ {'Cash On Delivery','Card','Bank'}
The seeder inserts an admin, categories, products, and payment methods. It’s idempotent — safe to run multiple times.
- Admin:
admin/P@ssw0rd!(stored as SHA-256 hex) - Categories: Postcards & Stationery, Magnets, T-Shirts & Apparel, Mugs & Drinkware, Keychains
- Payment Methods: Cash On Delivery, Card, Bank
- Products: several with price/stock (images optional under
Assets/images/products/)
Prefer SQL? You can manually run INSERTs that match the same values; the app’s seeder performs existence checks first.
- Admin › Products: CRUD, image upload, filters (name/category/visibility/sort), pagination, total count
- Admin › Categories: CRUD; prevents delete if referenced by products
- Admin › Members: list with full-name filter + date range, totals, pagination
- Admin › Orders: status tabs with counts (PENDING/ACCEPTED/DELIVERING/DELIVERED/CANCELED), filters (code, customer, date range), pagination
- OrderView: allowed transitions only
- pending → accepted → delivering → delivered
- cancel only from pending (and cancel returns stock to inventory)
- DB stores lowercase status; UI shows UPPERCASE
- shows items, shipping address, logs
- Feedbacks: pending/complete tabs; admin reply marks resolved
- Reports: inline data + hidden-iframe print templates
Admin/Reports.aspx shows controls and data inline. Clicking Print loads a hidden iframe:
Admin/ReportProduct.aspx— Product Stock ReportAdmin/ReportOrder.aspx— Delivered Orders Revenue Report (by date range / month / year)
Templates auto-invoke window.print() and use a .print-area CSS to print only the report (Admin chrome hidden).
<connectionStrings>
<add name="DefaultConnection"
connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Serena.mdf;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings><appSettings>
<add key="SetupKey" value="9C4F9E3B-7AD1-4E6D-AD13-6B9B1DB6F5E8" />
</appSettings>Security: rotate/remove the SetupKey and/or delete
Setup.aspxafter initialization. Set<compilation debug="false">in production.
-
Login works once, then fails after recycle
Ensureadmins.persistent_token/token_expiresexist (migrations add them) and cookies aren’t blocked. -
Print shows sidebar
Confirm report templates include the.print-areaCSS and are loaded in the hidden iframe fromAdmin/Reports. -
SQL permission errors
DB user must be able to CREATE TABLE/INDEX/CONSTRAINT for migrations. -
Payment methods constraint
Values must be exactlyCash On Delivery,Card, orBank. -
Images
Store relative paths likeAssets/images/products/filename.jpg; directory must be writable.
- Remove or protect
Setup.aspx(rotate/deleteSetupKey) - Change default admin password
-
<compilation debug="false">inWeb.config - Backup DB +
Assets/images/products - Restrict
/Admin/*to authenticated users - Validate file upload size/type in production