The new blog system for https://edi.wang. Written in C# on .NET Core and runs on Microsoft Azure.
Basic: Post, Comment, Category, Archive, Tag, Page, Friendlink
Misc: Pingback, RSS/Atom/OPML, Open Search, Reader View
This is NOT a general purpose blog system like WordPress or other CMS. Currently it contains content "hard coded" for https://edi.wang. To make it yours, you will need to change a certain amount of code.
The following tools are required for development.
Tools | Alternative |
---|---|
.NET Core 2.2 SDK | N/A |
Visual Studio 2019 | Visual Studio Code |
Azure SQL Database | SQL Server 2017 / LocalDB (Dev Only) |
Create an SQL Server 2017 LocalDB database. e.g. moonglade-dev
Create an Azure SQL Database or a SQL Server 2017+ database. e.g. moonglade-dev
Update the connection string "MoongladeDatabase" in appsettings.[env].json according to your database configuration.
Example:
"ConnectionStrings": {
"MoongladeDatabase": "Server=(localdb)\\MSSQLLocalDB;Database=moonglade-dev;Trusted_Connection=True;"
}
The blog will automatically setup datbase schema and initial data in first run
-
Create an "appsettings.Development.json" under "src\Moonglade.Web", this file defines development time settings such as accounts, db connections, keys, etc. It is by default ignored by git, so you will need to manange it on your own.
-
Build and run Moonglade.sln
Below section discuss system settings in appsettings.[env].json. For blog settings, please use "/admin/settings" UI.
Configure how to sign in to admin portal.
Register an App in Azure Active Directory
- Set Redirection URI to "https://yourdomain/signin-oidc"
- For local debugging, set URL to https://localhost:5001/signin-oidc
- Copy "appId" to set as AzureAd:ClientId in appsettings.[env].json file
"Authentication": {
"Provider": "AzureAD",
"AzureAd": {
"Domain": "{YOUR-VALUE}",
"TenantId": "{YOUR-VALUE}",
"ClientId": "{YOUR-VALUE}",
}
}
Set Authentication:Provider to "Local" and assign a pair of username and password.
Currently password is not encrypted, use it at your own risk.
"Authentication": {
"Provider": "Local",
"Local": {
"Username": "{YOUR-VALUE}",
"Password": "{YOUR-VALUE}",
}
}
AppSettings:ImageStorage controls how blog post images are stored. There are 2 built-in options:
Preferred: Azure Blob Storage
You need to create an Azure Blob Storage with container level permission.
"Provider": "azurestorage"
"AzureStorageSettings": {
"ConnectionString": "YOUR CONNECTION STRING",
"ContainerName": "YOUR CONTAINER NAME"
}
"Provider": "filesystem",
"FileSystemSettings": {
"Path": "${basedir}\\UploadedImages"
}
The Path can be relative or absolute. "${basedir}" represents the website's current directory. Storing images files under website directory is NOT recommended.
If GetImageByCDNRedirect is set to true, the blog will get images from client browser using a 302 redirect, not by fetching images in backend and put into memory cache. This is especially useful when you have a CDN for your image resources, like what I did on Azure.
"CDNSettings": {
"GetImageByCDNRedirect": true,
"CDNEndpoint": "https://ews.azureedge.net/ediwang-images"
}
Encryption controls the IV and Key for encrypted email passwords in database.
The blog will try to generate a pair of Key and IV on first run, and write values into appsettings.[Current Environment].json only. This means the application directory must NOT be read only. You'll have to set keys manully if you must use a read only deployment.
This blog generates robots.txt based on configuration. However, if there are a physical file named "robots.txt" under "wwwroot" directory, it will override the configuration based robots.txt generation.
To customize robots.txt, modify the configuration under RobotsTxt section.
Key | Description |
---|---|
CaptchaSettings:ImageWidth | Pixel Width of Captcha Image |
CaptchaSettings.ImageHeight | Pixel Height of Captcha Image |
TimeZone | The blog owner's current time zone (relative to UTC) |
PostSummaryWords | How may words to show in post list summary |
ImageCacheSlidingExpirationMinutes | Time for cached images to expire |
EnableImageLazyLoad | Use lazy load to show images when user scrolls the page |
EnablePingBackReceive | Can blog receive pingback requests |
EnablePingBackSend | Can blog send pingback to another blog |
EnforceHttps | Force website use HTTPS |
DisableEmailSendingInDevelopment | When debugging locally, do not send email for real |
DNSPrefetchEndpoint | Add HTML head named "dns-prefetch" |
The only built-in rule is removing trailing slash in URLs. For other rules, you can customize by editing "\src\Moonglade.Web\urlrewrite.xml" according to IIS URL Rewrite Module configuration
Not yet. Currently it depends on whether the database schema is changed. If the schema is same for a higer version, then the system can be deployed and override old files without problem.
No, the system design does not couple with Azure, but the blog works best on Azure. Every part of the system, like Authentication and Image Storage, can be configured to use non-Azure options.
- Microsoft Azure DNS Zones
- Microsoft Azure App Service
- Microsoft Azure SQL Database
- Microsoft Azure Blob Storage
Below open source projects are reusable components (NuGet packages) used in my blog, and they can be used in other websites as well.