Thanks for visiting my blog!
A while back, I decided that this blog deserved a clean coat of paint and since I’m digging into ASP.NET Core, it was logical to re-write it. I wanted more than just to change the look, I wanted to make some real changes to the code and finally open source the code too!
Open sourcing the code required that I do a few things. First of all, I had to change any code that I would be embarrassed by (not a trivial task), but also make it so that much of normal secrets weren’t exposed by open sourcing it (e.g. connection strings, etc.). But as of now, I’ve done it. The source is available and the site is live! I am sure that there are issues with the site, but hopefully I’ll iron those out as they crop up.
My goal here wasn’t to build a blog engine. This isn’t a carefully designed and architected solution that is easily skinned for your site, but it should be a good start to understand how to build a site with ASP.NET Core and related technologies. You can see the code here:
What I Used
I decided to build the site using as many new technologies as possible as this is my opportunity to learn the new stacks. This does mean that as each of the technologies are updated and released, that I need to keep up with those changes. That’s not a trivial decision. But each upgrade is a learning opportunity. The technologies I used to build it include:
- ASP.NET Core 1.0 RC1 (including MVC 6)
- Entity Framework 1.0
- Angular 2
- Bootstrap 4
- Azure Websites and Azure Blob Storage
All of these technologies are in flux, so as they’re updated you’ll probably hear me complain on twitter. Sorry for that.
The Trouble with .NET Core
I made the decision early on to target DNXCore and DNX451. That meant that when I ran into tools that I needed that weren’t available for .NET Core yet that I had to find alternatives.
My first challenge was email. I wanted a way to send email but in .NET Core there isn’t a System.Net.Mail system. So I decided to use a mailing service instead. I signed up for a SendGrid account and since I send so few emails it should be free. It supports a simple REST service to send mail, so it was relatively simple to set up. You have to search for the free 12K (12,000 emails a month) account, but it’s possible.
The next challenge was in supporting RSS. I couldn’t find any .NET Core packages that could generate an RSS feed, but it’s pretty simple so I wrote one. You can use it too. I’ve released it on GitHub and Nuget:
I used to deploy all the resources for the site just as part of the source code. I didn’t want to do that with an open source project. So instead, I decided to use Azure Blob Storage to do it. Getting my images and downloads into Azure was easy, but doing it programmatically inside the app was a bigger challenge. There are many ways of pushing new resources into Blob Storage, but to support .NET Core I found a specific version of the WindowsAzure.Storage Nuget package (version** 6.1.1-preview**) that support .NET Core. I am sure that there will be an update that also supports it, but for now that version works great.
The last real challenge was a bigger problem: Live Writer support. I use Live Writer to author my posts. I like that it works offline when I don’t have internet. But implementing the XML RPC was non-trivial. But like the RSS support, I’ve released it on Github and Nuget:
Handling Secrets
The last big challenge was how to share the source code without compromising any of the secrets that I needed to run the website. The trick was to use ASP.NET Core’s configuration system. I love how this stuff works. For example, when I set up the configuration for the project like this:
var builder = new ConfigurationBuilder()
.SetBasePath(appEnv.ApplicationBasePath)
.AddJsonFile("config.json")
.AddEnvironmentVariables();
This works because the Environment Variables can be used to override the values. So my config.json is safe to check in:
{
"WilderDb": {
"OldConnectionString": "...",
"ConnectionString": "...",
"TestData": "True"
},
"Disqus": {
"BlogName": "wildermuth"
},
"MailService": {
"ApiKey": "FOOBAR",
"ApiUser": "FOOBAR",
"Receiver": "shawn@wildermuth.com"
},
"MetaWeblog": {
"StoragePath": "/img/media/"
},
"AdService": {
"Client": "Add Google Client ID",
"Slot": "Add Ad Slot Number"
},
"Google": {
"Analytics": "Get Your GA Number"
},
"BlobService": {
"Account": "FOO",
"Key": "BAR"
}
}
On my local development machine, I set up environment variables to override these values (e.g. “BlogService:Account” is the environment variable that I can put the real account name in). Then when I deploy to Azure Websites, I just use the AppSettings which get translated into environment variables inside the app:
If you find a bug or issue, please help me out and put in an Issue or Pull Request to the repository and I’ll get it addressed as soon as I can. I’ll update this for the ASP.NET Core 1.0 RC2 and RTM when they ship too.
Let me know what you think!