A full-featured, RTL Persian blog engine built with ASP.NET Core 5, Entity Framework Core, and SQL Server β featuring a clean layered architecture, a public blog website, and a full admin panel for content management.
Blog.Web is a complete content-management solution for running a Persian (Farsi) blog:
- A public website (Razor Pages) where visitors browse posts by category, read articles, search, and leave comments β with a fully RTL UI based on the Mag template and the IRANSans font.
- An admin panel (MVC Area) based on AdminLTE 3 where administrators manage posts, categories, and users, with CKEditor 4 for rich-text authoring and image uploads.
- A 3-layer architecture that cleanly separates data access, business logic, and presentation.
| Author | Mohammad Hasan Pirayandeh (@MohammadHasanp) |
| Stack | C# / .NET 5, ASP.NET Core (MVC + Razor Pages), EF Core, SQL Server |
| Language of UI | Persian (RTL) |
| Database | SQL Server (code-first with migrations) |
- π Home page β latest posts, special/featured posts, popular posts (loaded via AJAX), and a category navigator with post counts
- π Post pages with SEO-friendly slug URLs (
/Post/{slug}), visit counters, related posts, and a comment form - π Search with filtering by keyword and category, plus pagination
- π Nested categories (main categories + subcategories) with SEO meta tags & meta description
- π€ User registration & login (cookie authentication, 30-day persistent session)
- π‘ Custom error pages (404 / 500)
- π Dashboard (AdminLTE 3, RTL)
- βοΈ Posts management β create/edit/delete with CKEditor 4 rich-text editor, cover image & in-content image upload, slug uniqueness check, special-post flag
- π Categories management β hierarchical (parent/child), SEO fields
- π₯ Users management β search, pagination, edit user info & roles (Admin / Writer / User), modal-based editing
- π Role-based authorization β the whole admin area is protected by an
adminPolicyrequiring the Admin role
- Clean 3-layer design with dependency injection everywhere
- Service interfaces + implementations (
IXxxServiceβXxxService) - DTO layer for all inputs/outputs, with dedicated mapper classes
- OperationResult pattern for consistent success/error results
- Reusable utilities: slug generator, MD5 password encoder, image validation, pagination helper, date helpers, file manager for uploads
- Soft-delete support (
IsDelete) and audit timestamp (Time) built intoBaseEntity
flowchart TD
A[Blog.Web β Presentation<br/>Razor Pages + MVC Admin Area] --> B[Blog.CoreLayer β Business Logic<br/>Services Β· DTOs Β· Mappers Β· Utilities]
B --> C[Blog.DataLayer β Data Access<br/>BlogContext Β· Entities Β· Migrations]
C --> D[(SQL Server β Blog_db)]
| Layer | Project | Responsibility |
|---|---|---|
| Presentation | Blog.Web |
Public Razor Pages site + /Admin MVC area, authentication & authorization, static assets (wwwroot) |
| Business Logic | Blog.CoreLayer |
Services (Posts, Categories, Users, Comments, MainPage, FileManager), DTOs, mappers, cross-cutting utilities |
| Data Access | Blog.DataLayer |
EF Core BlogContext, entities, code-first migrations, SQL Server configuration |
| Technology | Usage |
|---|---|
| C# / .NET 5 | Target framework (net5.0) |
| ASP.NET Core MVC | Admin panel (Areas, controllers, views) |
| Razor Pages | Public website pages |
| Entity Framework Core | ORM, code-first migrations |
| SQL Server | Database (Blog_db) |
| Cookie Authentication | Login / registration, role-based policies |
| AdminLTE 3 (RTL) | Admin panel template |
| Mag template + IRANSans | Public RTL theme |
| CKEditor 4 | Rich-text editor with image upload |
| Bootstrap Β· jQuery Β· Chart.js | Front-end assets |
Blog.Web/
βββ Blog.sln # Solution (3 projects)
β
βββ Blog.Web/ # π₯ Presentation layer (ASP.NET Core 5)
β βββ Program.cs / Startup.cs # Host, DI registrations, auth & routing config
β βββ Pages/ # Public site (Razor Pages)
β β βββ Index.cshtml # Home page (latest, special & popular posts)
β β βββ Post.cshtml # Post detail + comments (slug-routed)
β β βββ Search.cshtml # Search by keyword & category
β β βββ Auth/ # Login / Register / Logout
β β βββ Shared/ # Layouts, header, footer, partial views
β βββ Areas/Admin/ # Admin panel (MVC area, Admin policy)
β β βββ Controllers/ # Home, Post, Category, User, Upload
β β βββ Models/ # View models (create/edit)
β β βββ Views/ # AdminLTE views + editor templates
β βββ Controllers/ # ErrorHandler (custom 404 / 500 pages)
β βββ TagHelpers/ # Custom OpenModal tag helper
β βββ appsettings.json # Connection string & logging config
β βββ wwwroot/ # Static assets (css, js, images, CKEditor, AdminLTE)
β
βββ Blog.CoreLayer/ # π§ Business logic layer (class library)
β βββ Services/
β β βββ Posts/ # Post CRUD, filtering, slugs, visits, related posts
β β βββ Categoryes/ # Category CRUD & slugs
β β βββ Users/ # Register, login, edit, filtering
β β βββ Comment/ # Comments CRUD
β β βββ Mainpage/ # Aggregated home-page data
β β βββ FileManager/ # Save/delete files & images on disk
β βββ Dtos/ # Data-transfer objects per feature
β βββ Mpperes/ # Entity β DTO mappers
β βββ Utilities/ # OperationResult, pagination, slug & date
β # helpers, MD5 encoder, image validation
β
βββ Blog.DataLayer/ # π Data access layer (class library)
β βββ Context/BlogContext.cs # EF Core DbContext (Posts, Users, Categories, Comments)
β βββ Entyties/ # User, Post, Category, PostComment, BaseEntity
β βββ Migrations/ # Code-first EF migrations
β
βββ Mag/ # π¨ Original "Mag" HTML template (public theme source)
βββ admin/ # π¨ Original AdminLTE HTML template (admin theme source)
βΉοΈ
Mag/andadmin/hold the original static HTML templates the site themes were built from; the compiled assets actually used by the app live underBlog.Web/wwwroot/.
| Entity | Description |
|---|---|
| User | Username, full name, password (MD5-hashed), UserRole enum (Admin / Writer / User) |
| Post | Title, slug, description (HTML), cover image, visit counter, IsSpecial flag, links to author, category and optional subcategory |
| Category | Title, slug, SEO meta tag & description, optional ParentId (self-referencing hierarchy) |
| PostComment | Comment text, linked to a user and a post |
| BaseEntity | Shared base: primary key, creation Time, IsDelete soft-delete flag |
All foreign keys are configured with cascade delete.
- .NET 5 SDK
- SQL Server (LocalDB or a full instance)
- (Optional) Visual Studio 2019/2022 or VS Code
# 1. Clone the repository
git clone https://github.com/MohammadHasanp/Blog.Web.git
cd Blog.Web
# 2. Check the connection string (Blog.Web/appsettings.json β "Defualt")
# Default: Server=.;Database=Blog_db;Integrated Security=true
# 3. Create / update the database from the code-first migrations
dotnet tool install --global dotnet-ef # if not installed
dotnet ef database update --project Blog.DataLayer --startup-project Blog.Web
# 4. Run the app
dotnet run --project Blog.WebThen browse to https://localhost:5001 (public site) or /Admin (admin panel).
There is no seeded admin account. To gain access to the admin panel:
- Register a normal account on the site at
/Auth/Register. - Promote it to the
Adminrole in the database:
UPDATE Users SET Role = 0 /* Admin */ WHERE UserName = 'your_username';- Log in again and open
/Admin.
Blog.Web/appsettings.json:
"ConnectionStrings": {
"Defualt": "Server=.;Database=Blog_db;Integrated Security=true;MultipleActiveResultSets=true"
}Uploaded post images are stored under wwwroot/images/posts (content images under .../posts/content) β see Directories.cs in the CoreLayer.
- β¬οΈ Upgrade from .NET 5 (EOL) to a supported .NET version
- π Replace MD5 password hashing with a modern KDF (PBKDF2 / BCrypt)
- π§ͺ Add unit/integration tests
- π Multi-language support (currently Persian-only)
- π Dashboard statistics widgets with Chart.js
Mohammad Hasan Pirayandeh β @MohammadHasanp
π§ PirayandehMohammadHasan@gmail.com
- AdminLTE 3 β admin panel template
- CKEditor 4 β rich-text editor
- Bootstrap & jQuery β front-end framework
- Mag HTML template β public theme basis
- Entity Framework Core β ORM
β If you like this project, please consider giving it a star on GitHub! β