Pegasus
ASP.NET Core Blog Engine

Pegasus 🦄 is an awesome blog engine written in C#, built with .NET 9, ASP.NET Core, and Angular. I built it myself, it's my baby. If you're interested in learning more about it, continue reading.
Features
Here's a high-level overview of the core features.
Categories
Pegasus supports flat categories, posts can be assigned to multiple categories at a time.
Tags
You can define as many tags as you like. Posts can have multiple tags too.
Posts
Blog posts are written in HTML, using TinyMCE as the editor. You can configure the following for each post.
Published date and time
Posts can be back-dated to whatever date and time you like.
Status & visibility
- Draft/Published
- Private/Public
- Featured
Permalink
The URL slug for each post. You can leave it blank and have it generated from the title, or you can choose whatever you like.
Metadata
The meta description used for SEO, RSS feeds, etc.
Categories
You can select categories from a check list, or add new ones on the fly.
Tags
You can select tags from an autocomplete list, or add new ones on the fly.
Cover image
Each post is required to have a cover image. This ensures a consistent layout and proper SEO data.
You can upload your own image, or enter a URL. Fallback directives apply a placeholder to broken images.
Comments
Allow comments (if turned off, comments and replies won't be accepted).
User comments are stored in-house in the database, supporting a hierarchical structure. I wanted user comments to be part of the database, but you could easily turn it off and use something else like Disqus. Comments are written in HTML too, using TinyMCE as the editor, but only support a subset of editing features. By default, comments need moderation before they go live. You can manage comments in the admin dashboard.
Article Series
Pegasus implements article series for managing multi-part articles.
You can create article series, assign posts to them, reorder the series and their parts via a user-friendly UI.
Smart navigation controls and UI components are implemented for easy discovery and user engagement.
Search
Search through articles, categories, and tags.
Pegasus implements a paginated search function that uses relevance scoring for more accurate and helpful results.
Feeds
The blog feed is available in RSS. Additionally, each category and tag has an RSS feed. There's also an OPML feed, look here for more information. An XML sitemap is generated too, mainly for search engines, but could be used for other needs as well.
Export/Import
You can export the data to an XML file, or a Zip archive. The zip archive includes the XML file, plus the images folder (cover and in-post images). The import feature allows you to upload the XML file or the Zip archive. One good thing about the import feature is that it patches your data. Say you export everything to XML, then delete a few comments, make changes to some posts, etc. When you import the XML file, Pegasus checks for already existing objects in the database. If something is not found, it will insert it in the database. Otherwise, it scans the entities and updates missing information. For example, if you have a blog post with 10 comments and you delete 3 of them, when you import the data, the blog post and its related information won't be touched (the post entity, categories and tags, etc.) but the missing 3 comments will be restored.
I needed the import/export functionality because it's always best to be able to export the data via the app itself. Without this, I would have needed to backup the database manually, or generate SQL scripts, etc. This way, I can easily export/import whenever needed without having to access the hosting server. Plus, having the raw data in XML format means I can do more with it. Let's say I wanted to write a desktop client to read the data, or perhaps I want to transform the data and extract some information, you get the gist.
Settings
All application and external settings live in the appsettings.json file. This includes the application settings, search engine verification codes, reCAPTCHA keys, etc.
Account settings
You can change your password, enable two-factor authentication, or recover your account in case you forget your password.
App settings
You can configure the application behavior and static values used across the site:
- Site name & version
- Author information (name, email, social profiles)
- Blog information (title, description, posts per page, etc.)
- Feed information (used by RSS feeds)
- SMTP settings (used for outgoing emails)
Search Engines
You can configure multiple search engines by providing their verification codes. The appropriate meta tags will be injected in the main layout. Google and Bing verification codes are required to ensure you cover 98% of the market share by default.
Security
Pegasus uses JWT and Cookies for authentication, and role-based authorization for securing API endpoints.
Proper CSPs (Content Security Policy) and response headers are applied to all requests, ensuring maximum security.
SEO
Pegasus implements a rock-solid foundation for injecting SEO metadata and structured JSON-LD scripts on every page.
You get well structured, schema compliant metadata for search engines, crawlers and social bots alike.
Content Security Policy
Pegasus implements a CSP builder and a security headers middleware. Different policies are applied to different parts of the app which gives you granular control and a maintainable and easy-to-customize foundation.
Health Checks
Health checks are configured and accessible via a secured UI to enable seamless monitoring of the web app and resources in use.
Tech Stack
| Programming language | C# |
| Platform | .NET 9 |
| Web Framework | ASP.NET Core |
| Data Access | Entity Framework Core |
| Database Engine | SQL Server |
| CSS Framework | Bootstrap 5.3.8 |
| Front-end Framework | Angular 20.3.7 |
| Background Processing | Hangfire |
Pegasus uses many open source libraries, including but not limited to:
- ng-bootstrap - native bootstrap components for Angular
- ng-select - autocomplete component for Angular
- ngx-progressbar - nano progress bar for Angular
- tinymce-angular - TinyMCE integration for Angular
- animate.css - CSS entrance/exit animations
- jQuery - for DOM manipulation
- moment - JavaScript date library
- ngx-moment - Angular pipes for moment functions
- ngx-toastr - Angular wrapper for Toastr.js
Where can I get it?
Although Pegasus is production ready and stable, it's still in active development. I'm planning to open source the project on GitHub. I am going to publish the source code under MIT. Looking forward to see how it's going to be received by the community and if anyone's going to use it on the web. I think .NET developers are going to love it, and who knows, maybe I'll develop Pegasus further into a full blown blog engine in the future.
Background
A few years ago I built a web app for myself using ASP.NET MVC on .NET Framework 4.5. I wanted to have a have a website and tech blog about my work, but I didn't want to use ready-made software. There are numerous open source and free products available, from WordPress and Orchard, to static site generators like Ghost, and Hugo. I wanted to build everything myself to learn more and master my craft. It served me very well as it turned out to be an invaluable opportunity for growth. Over the past few years, this project served as my pet project to try new things and develop my skills further as a software engineer.
Since the first release, I didn't get to blog as much as I liked to. I've been swamped with work. Around mid 2020s I updated the project and cleaned up the code to get ready for serious blogging. But the project was outdated and I was in the middle in of upgrading to .NET Core and Angular 2+. So I thought this is a great opportunity to rewrite the project from scratch and migrate to new technologies.
Around March 2020, I started rewriting Pegasus and at the time .NET Core 3.0 was available, which was great. At first, I wanted to move away from ASP.NET MVC and built a RESTful API with an Angular SPA. The development experience is great when you're working in that setting. Great performance, easy to maintain, TypeScript and Angular components, it's a delight. But soon I realized it won't scale well because SPAs aren't easily SEO-friendly. Of course there are ways to help you rectify, server-side rendering and static site generators, etc. But all that turned out to be overkill and required a lot more work that necessary.
So, I took a break and refactored the solution. I didn't want to lose the Angular SPA and my RESTful API. What I wanted to achieve was, a well structured and performant web application that serves server-side rendered views, with an Angular SPA for the admin dashboard. It took me a few months to put everything together, but it was well worth the effort. I'm very pleased with the end result and everything works great. There's always room for improvement, obviously, and I try to actively maintain the project.