Full-stack event management platform built with ASP.NET Core 9 Web API and Blazor WebAssembly. Organizers publish events with tiered tickets, clients register and pay, a waiting list takes over when an event is sold out, and administrators manage organizers and approve speakers.
| Role | What they can do |
|---|---|
| Visitor | Browse published events, simple and advanced search, view event details (venue, speakers, ticket types, remaining seats) |
| Client | Register and log in · book tickets (VIP / Premium / Regular) with a payment method · join the waiting list when an event is sold out · view and cancel their own registrations · manage their profile |
| Organizer | Create events (as drafts), edit, publish and cancel their own events · define ticket types, prices and capacities · manage venues · propose and edit speakers (approved by an admin) · view the waiting list of their events · sales statistics |
| Admin | Dashboard (all events, drafts included) · add, search and delete organizers · organizer and speaker statistics · approve, reject and delete speakers · manage and delete venues · view all registrations and the whole waiting list |
- Every write endpoint requires a JWT and a role; ownership is checked on the server (
403 Forbiddenotherwise). - The organizer of an event and the user of a registration are read from the token, never from the request body.
- Drafts are only visible to their organizer and to administrators; personal data (registrations, waiting lists) is restricted to its owner, the event's organizer or an administrator.
- Request bodies are DTOs (no entity binding), validated with data annotations.
- No secret is committed: the JWT signing key comes from
dotnet user-secrets(or an environment variable), and the API refuses to start without it. - CORS only allows the origins listed in
Cors:AllowedOrigins.
| Home | Events |
|---|---|
![]() |
![]() |
| Event details & booking | My registrations |
|---|---|
![]() |
![]() |
| Organizer — event editor | Organizer — sales statistics |
|---|---|
![]() |
![]() |
Admin dashboard
flowchart LR
subgraph Client["Browser"]
B["Blazor WebAssembly<br/>FrontEnd"]
end
subgraph API["ASP.NET Core 9 Web API — EventWave"]
C["Controllers"] --> S["Services"] --> R["Repositories"]
R --> EF["EF Core<br/>ApplicationDBContext"]
ID["ASP.NET Identity<br/>+ JWT"]
end
DB[("SQL Server")]
B -- "HTTP + Bearer JWT" --> C
EF --> DB
ID --> DB
Back-end (EventWave/)
- Layered architecture: Controllers → Services → Repositories, with DTOs and dependency injection
- Entity Framework Core (code-first, migrations) on SQL Server
- ASP.NET Identity with roles (
Admin,Organizer,Client) and JWT authentication - Business rules: ticket capacity per type, numbered tickets, automatic waiting list, event lifecycle (Draft → Published → Cancelled)
- Seeders for roles, admin account and Tunisian demo data
Front-end (FrontEnd/)
- Blazor WebAssembly with a custom
AuthenticationStateProviderthat reads the JWT (token kept inlocalStorage) DelegatingHandlerthat adds theAuthorization: Bearerheader to every API call- Role-based navigation and pages (
[Authorize(Roles = ...)]), typed API services, reusable components (cards, modals, badges, stat cards)
erDiagram
USER ||--o| PROFILE : has
USER ||--o{ REGISTRATION : makes
USER ||--o{ WAITLIST : joins
VENUE ||--o{ EVENT : hosts
SPEAKER ||--o{ EVENT : "speaks at"
EVENT ||--o{ TICKET_TYPE_CAPACITY : offers
EVENT ||--o{ REGISTRATION : receives
EVENT ||--o{ WAITLIST : has
REGISTRATION ||--o{ TICKET : contains
EVENT {
int Id
string Title
datetime Start
datetime End
string Category
string Status "Draft | Published | Cancelled"
string OrganizerId
}
TICKET_TYPE_CAPACITY {
string TicketType "VIP | Premium | Regular"
int Capacity
int TicketsRemaining
decimal Price
}
REGISTRATION {
decimal TotalAmount
string PaymentMethod "CreditCard | DebitCard | MobileWallet"
datetime RegisteredAt
}
TICKET {
string TicketNumber
string Type
decimal Price
}
WAITLIST {
int TicketCount
string TicketType
datetime CreatedAt
}
SPEAKER {
string Name
string Expertise
bool IsApproved
}
VENUE {
string Name
string City
int Capacity
}
| Method | Route | Access |
|---|---|---|
POST |
/api/auth/register · /api/auth/login |
Public |
GET |
/api/events · /api/events/search?q= · /api/events/search/advanced |
Public (published and cancelled events) |
GET |
/api/events?all=true |
Admin (drafts included) |
GET |
/api/events/{id} |
Public; a draft only for its organizer or an admin |
GET |
/api/events/mine |
Organizer (own events, drafts included) |
GET |
/api/events/organizer/stats |
Organizer (own sales) |
POST |
/api/events |
Organizer (created as a draft) |
PUT |
/api/events/{id} |
Organizer, owner of the event |
PATCH |
/api/events/{id}/publish · /api/events/{id}/cancel |
Organizer, owner of the event |
GET |
/api/registration |
Admin |
GET |
/api/registration/me |
Authenticated user |
GET |
/api/registration/{id} |
Owner of the registration or Admin |
POST |
/api/registration |
Client (confirmed booking, waiting list or error) |
DELETE |
/api/registration/{id} |
Owner of the registration or Admin |
GET |
/api/waitlist |
Admin |
GET |
/api/waitlist/me |
Authenticated user |
GET |
/api/waitlist/event/{eventId} |
Organizer of the event or Admin |
GET |
/api/speaker · /api/speaker/{id} |
Public |
POST · PUT |
/api/speaker · /api/speaker/{id} |
Organizer, Admin (the approval status cannot be changed here) |
DELETE |
/api/speaker/{id} |
Admin |
GET |
/api/venues · /api/venues/{id} |
Public |
POST · PUT |
/api/venues · /api/venues/{id} |
Organizer, Admin |
DELETE |
/api/venues/{id} |
Admin |
GET · POST · PUT |
/api/profile/me · /api/profile |
Authenticated user (own profile) |
GET · POST · DELETE |
/api/admin/organizers · /search · /{id} · /{id}/stats · /api/admin/add-organizer |
Admin |
GET · PUT |
/api/admin/pending-speakers · /approve-speaker/{id} · /reject-speaker/{id} · /speakers/search · /speakers/{id}/stats |
Admin |
Unauthenticated calls to a protected endpoint return 401, calls with the wrong role or on someone else's data return 403.
Requirements: .NET 9 SDK, SQL Server (or LocalDB, installed with Visual Studio), Visual Studio 2022 17.12+ (optional).
- Clone the repository
git clone https://github.com/MaatarChaima/EventWave.git cd EventWave - Set the JWT signing key.
JWT:SecretKeyis intentionally empty inappsettings.jsonand the API refuses to start without it. Store a random key (at least 32 characters) with user secrets:# PowerShell: generates a 64-byte random key and stores it outside the repository $key = [Convert]::ToBase64String([Security.Cryptography.RandomNumberGenerator]::GetBytes(64)) dotnet user-secrets set "JWT:SecretKey" $key --project EventWave
- Database. By default the API uses LocalDB:
Server=(localdb)\MSSQLLocalDB;Database=EventWaveDB;Trusted_Connection=True;TrustServerCertificate=True;. To use another SQL Server instance without touchingappsettings.json, override the connection string with a user secret:Then create the database:dotnet user-secrets set "ConnectionStrings:cnx" "Server=<YOUR-PC>\<INSTANCE>;Database=EventWaveDB;Integrated Security=True;TrustServerCertificate=True;" --project EventWave
User secrets are only loaded in thedotnet tool install --global dotnet-ef dotnet ef database update --project EventWave
Developmentenvironment (thehttplaunch profile). In production, use environment variables instead (JWT__SecretKey,ConnectionStrings__cnx). - Run the API and the front-end (two terminals):
In Visual Studio: Configure Startup Projects → Multiple startup projects, start EventWave then FrontEnd, both with the
dotnet run --project EventWave --launch-profile http # http://localhost:5063 dotnet run --project FrontEnd --launch-profile http # http://localhost:5078
httpprofile.
Demo data (venues, speakers, events, registrations in Tunisia) is created at startup when DemoData:Seed is true
(see EventWave/appsettings.Development.json). The front-end reads the API URL from FrontEnd/wwwroot/appsettings.json,
and the API accepts the front-end origins listed in Cors:AllowedOrigins.
Created by the seeders on a fresh database:
| Role | Password | |
|---|---|---|
| Admin | admin@test.com |
Admin123! |
| Organizer | organizer@test.com |
Demo123! |
| Client | client@test.com |
Demo123! |
More accounts are listed in TEST-ACCOUNTS.md.
EventWave.sln
├── EventWave/ ASP.NET Core 9 Web API
│ ├── Controllers/ REST endpoints
│ ├── Services/ Business logic
│ ├── Repositories/ Data access (EF Core)
│ ├── Models/ Entities
│ ├── DTOs/ Data transfer objects
│ ├── Data/ DbContext and seeders
│ └── Migrations/ EF Core migrations
└── FrontEnd/ Blazor WebAssembly
├── Auth/ JWT authentication state, token storage, auth header handler
├── Pages/ Public, Client, Organizer and Admin pages
├── Components/ Reusable UI components
└── Services/ Typed API clients
Academic team project — 2025/2026.
- Chaima Maatar — GitHub
- Mariem Lanouar
- Salha Hentati







