Update: Due to new personal commitments and more work commitments in 2021, I wasn’t able to make much progress with my weekly C# A-Z series on dev.to/shahedc. For now, I’ll focus on some new content for my regular blog (this blog, WakeUpAndCode.com) and hope to revisit the A-Z series with .NET 6.
Original Post:
I published my first ASP .NET Core A-Z series on WakeUpAndCode.com back in 2019, from January to June 2019. I followed this with a new A-Z series in 2020, simultaneously mirroring the posts on dev.to as well.
Going forward, my next A-Z series will cover 26 topics covering various C# language features. The C# A-Z series will be featured exclusively on my dev.to site under the .NET org:
Meanwhile, this site (WakeUpAndCode.com) will continue to feature new ASP .NET Core content based on .NET 5, Blazor and more! To get a sneak peak of what’s to come, check out my guest appearance on the .NET Docs Show (livestreamed Dec 7, 2020). You may jump ahead to 58:05 in the video for the sneak peek:
The above video teases my upcoming cinematic visualizer app, which will allow the end user to connect the dots within a cinematic universe, e.g. the Marvel Cinematic Universe. The source code will allow any .NET developer to learn more about C# and .NET 5, ASP .NET Core, Entity Framework, Azure App Service, Bot Framework, Azure Functions, and more!
The goal of the web app is to make use of all 3 project styles available in ASP .NET Core:
MVC (Model View Controller)
Razor Pages
Blazor
Developers frequently ask the developer community (and Microsoft) whether a particular web project type is preferred over the other. Last year’s blog series built upon the NetLearner web app by duplicating identical functionality across all three project types. This year, the cinematic visualizer app will attempt to use each project type of something specific.
MVC for data entry
Razor Pages for the Portal site
Blazor for the highly interactive portion
The above choices aren’t necessarily prescriptive for the type of web apps they will demonstrate. However, they should provide a starting point when developing ASP .NET Core web applications.
Have you always wanted to start your own dev blog? Do you have one now? Do you blog regularly or is your blog inactive at the moment? I asked these questions via a Twitter Poll and got a variety of responses.
No matter where you are in your software development career, this blog post will help you on your blogging journey. Format your content, improve the material and promote it far and wide. Below are some tips I came up with, based on my personal experience blogging about .NET topics.
If you’re looking for my ASP .NET Core A-Z Blog Series, you may go directly to the following URL:
TIP #1: Format your blog content into sections with HTML headings.
HTML headings aren’t just for visual appeal. They can be used by screen readers to identify when a new section begins. They can also be used by search engines to identify those sections to be displayed in search engine results.
Take a look at these search results when you search for “Blazor shared libraries” in Bing and Google.
As you scroll through the first page of results, you’ll notice that the excerpt for my blog includes rich formatting for sections and their headings, where applicable.
On Bing, the H1 headings are extracted into clickable tabbed headers in the search results.
On Google, the H1 headings are displayed as clickable links underneath the excerpt, while a “Jump to” link is provided to jump directly to the relevant section.
2. Regular Frequency
TIP #2: Publish new content with regular frequency.
If you publish only one blog post, you may get lucky if some Internet users stumble upon your blog. But if you publish blog posts more often, especially with a predictable frequency, you may get repeat visitors who look forward to new content.
Take a look at my blog statistics from 2018 through 2020, to see how regular blog posts brought new/repeat visitors to my site.
Before October 2018, I barely had 2,000 views per month, as I did not publish any new/exciting content. I was mostly using my blog to upload my PowerPoint slides after a live presentation.
In late 2018, I published my first ASP .NET Core blog series, which ended up becoming a surprise HAPPY NEW YEAR series (revealed in December 2018). The 2018 series spiked in December 2018 (40k views) with .NET Core 3.0 coverage around Connect(); 2018.
From January 2019 through June 2019, I introduced my weekly A-Z series for various ASP .NET Core topics. This series resulted in gradual increase in viewership, including a spike (54k views) around the launch of Visual Studio 2019 and C# 8.0.
In July 2019, I released my free A-Z ebook, compiled from the 2018 A-Z series. This resulted in another spike (66k views) after the ebook was released, itself auto-generated using a .NET Core 3.0 Worker Service.
From January 2020 through June 2020, I published a new weekly A-Z series for similar ASP .NET Core topics. This now-annual series resulted in a steady level of views (60k+ views) each month that hovered near the previous year’s highs.
Around April 2020, there was a spike (80k+ views) which was a new record for my blog.
After July 2020, there was no new content, and the viewership continued to decline each month.
I’m currently planning new content for 2021, to focus on .NET 5 and C# 9 topics.
3. Relevant Content
TIP #3: Publish new content that is relevant to your intended audience.
It’s not just enough to format your content and publish with regular frequency. You should also try to maintain one or more themes for your blog, so that your readers can have an idea of what to expect.
In my case: I came up with topics that would be useful and relevant for a .NET developer, especially developers working with ASP .NET Core web apps and related technologies.
Take a look at the word cloud below to see popular search terms that led developers to my blog in 2019:
From the word cloud above, you can see that people searched for terms like ASP .NET Core, MVC, Controllers, Web API, cookie, storage, VS2019, hosting, signalr, tutorial and many more search terms!
4. Advertising & Promotion
TIP #4: Promote your work!
If a developer writes a blog in the forest, but there’s no one around to read it, did they even write a blog? This age-old philosophical question should help you think about ways to promote your work. But advertising isn’t just about spending money on online advertisements. In fact, I’ve personally found that it’s not worth it for me to spend any money on advertising.
Your mileage may vary.
Let me explain: I’ve never advertised my blog on Google or Bing (or any other search platform). Yet, my blog appears in top search results quite frequently. Organic search results are worth more to me than any paid results.
As for social media, I’ve launched a Facebook page called Shahed Codes:
This page has less than 1,000 followers as of this writing, yet I get a lot more views on my blog. That’s because I promote the posts from Shahed Codes in a couple of Facebook groups with a large number of .NET developers. I had briefly tried advertising on Facebook, but the engagement from free developer groups are significantly higher than any engagement for paid ads.
5. Facebook Groups
TIP #5: Consider sharing your work with other developers on Facebook.
Speaking of Facebook groups, there are countless Facebook groups dedicated to various topics related to software development. In my case, I joined a handful of .NET groups such as:
In the above screenshot, the post was shared to both DotNetCore Developers and ASP .NET Core groups, which resulted in over 8,000 people reached, just from a handful of shares. This reach would not have been possible if the original post wasn’t shared beyond the Shahed Codes page.
With permission from a group founder/admin, I shared my weekly posts from Shahed Codes to both of these groups, once for every new post. In case your readers have any feedback or follow-up questions, be prepared to respond to other developers who reach out to you.
You may also get request for 1:1 communications via private messages. Personally, I don’t have the bandwidth to help other developers via private messages, so I usually ask them to ask their questions in public posts/comments. I’ll try to help if time permits, but this approach also allows others to chime in as well.
To verify the thumbnail (or update the cached image), you may use the Facebook Link Sharing Debugger (aka Facebook URL Linter):
The first rule of Twitter is that there are no rules on Twitter. I’ve had a Twitter account since 2009, but rediscovered it in 2018, when I started sharing my weekly blog posts on Twitter.
My post popular post of all time made 1.8M impressions around the world, with a silly joke tweet in 2018. My post popular post in 2020 was a thoughtful tweet that resonated with a lot of people around the world, with 310k+ impressions. Somewhere in between, a nostalgic tweet about Visual SourceSafe made 158k+ impressions. My tweets about my dev blog posts usually reach much fewer people than any of these numbers.
That being said, the value of Twitter comes from the interactions with other developers. This includes Twitter users who are already using the technology you’re writing about, and others who are just starting out. Best of all, we can learn something from each other.
Every time you share your content on Twitter (with a few #hashtags if appropriate), you may reach new readers who are interested in your content. Just like on Facebook, you may get questions and feedback from others who are curious to learn more.
CAUTION: Inevitably, you may also get nasty comments from people who have nothing better to do with their time. Use your time wisely. If it’s constructive criticism, think about how you may use their feedback to improve your content. If they’re just being mean for no good reason, take a step back and ignore/mute/block the person as needed.
Note that URLs shared on Twitter may be converted to a t.co short URL in the post itself… BUT, the displayed URL should still show up as the correct URL. If the URL is too long, it may be truncated when displayed. The displayed thumbnail will also display a preview image and the domain of the clickable URL.
To verify the thumbnail (or update the cached image), you may use the Twitter Card Validator:
TIP #7: Reach out to others in your professional network and beyond.
You may not be active on LinkedIn, but it’s quite likely that you have a LinkedIn account. Depending on where your connections live, they are mostly likely active around the clock, day and night. If you haven’t been on LinkedIn for a while, try to visit the site/app occasionally to see when more people in your network are likely to view your future posts.
I’m not very active on LinkedIn myself, but I did share my weekly blog posts on the professional social network. This allowed me to reach additional .NET developers who may not be aware of my content posted to Twitter and Facebook. If I’ve worked with them before, it’s likely that they might be interested in the new content I’m sharing.
Similar to Twitter: Note that URLs shared on LinkedIn will be converted to a lnkd.in short URL in the post itself. This short URL may not be visible if it’s the last line of your post. To ensure that this URL appears as a clickable link in the post, add some additional text after the URL. The displayed thumbnail will also display a preview image and the top-level domain of the clickable URL.
To verify the thumbnail (or update the cached image), you may use the LinkedIn Post Inspector:
TIP #8: Update incorrect/outdated content but not too much.
By the time you read this post, some of the above content may become outdated. This is true for any dev blog post or tech book. What you do with outdated content is up to you. You could keep revising your content to correct obsolete/inaccurate sections, but that could prove to be an exercise in futility.
Worse yet, any posts or articles (your own or from others) may become inaccurate if they’re pointing to your updated content at the same old URL. To counter this, I suggest making only minor edits, including typo corrections and the addition of brief important notes to call out outdated content.
To publish new content that deviates significantly from the original content, I would suggest publishing a brand new blog post each time. This will let you pick a new SEO-friendly URL and create a new post that doesn’t mess with any references to the original post.
This is how I ended up with a new A-Z series for each year (2019 and 2020) so far.
The 2019 series started with .NET Core 2.2 and Visual Studio 2017, but got upgraded to .NET Core 3.0 and Visual Studio 2019 along the way.
With the new .NET release schedule (annual November releases), the 2020 series was able to maintain a single .NET version (.NET Core 3.1) and a single IDE version (Visual Studio 2019) throughout its publishing history.
9. Code Samples
TIP #9: Provide code samples, preferably linked to a public repository.
Back in 2018, my code samples were all over the place, in my GitHub repository:
In 2019, I decided to introduce a new web app called NetLearner. The goal was to update this repo as much as possible, but my code samples were still spread out across multiple repositories.
In 2020, I decided to introduce a new version of NetLearner, built on .NET Core 3.1. Better yet, I wrote a mini-series of “prelude” posts before the A-Z series to discuss the project structure and the purpose of the NetLearner project.
From January to June 2020, I continued to built the NetLearner app every week, with 26 releases over 26 weeks. As of October 2020, the alpha version has been deployed to a public website, to demonstrate its features:
TIP #10: Use YouTube videos to complement your blog posts.
My work has been featured on various YouTube channels, including the official .NET Community Standup and (coming soon) the .NET Docs show. I’ve also appeared on the Philly-based Dev Talk Show.
I do have my own YouTube channel, where I’ve published C# video tutorials many years ago. Going forward, I plan to publish new dev content on my YouTube channel:
I hope you’ve enjoyed this writeup and found something useful that you can implement in your own blogging journey. Feel free to reach out with any follow-up questions if you need any guidance for blogging.
Originally written up in a GitHub repo while helping out another developer, this blog post explains how you can debug multiple .NET Core projects in Visual Studio Code.
To download the sample code, clone the following GitHub repository:
Launch VS Code with the project root as the current working directory. One easy way to do this is to type the word “code” followed by a dot “.” at a Command Prompt, Powershell window or Windows Terminal.
Powershell/Terminal Command:
code .
If you already have VS Code open, use the built-in Terminal (Ctrl+`) to change the current directory to the project root.
In either case, you should end up with VS Code open with the Terminal open in the correction location (project root).
Launch Configuration
This project contains launch.json configuration for a .NET Core console project and a Web API projet.
Debug Panel
In the Debug Panel of VS Code, observe that you can see both configurations, ready for launch.
Setting Breakpoints
In the code for each project, set a breakpoint that’s easy to identify.
Debugging with Breakpoints
From the aforementioned Debug Panel, run the Web API project and then the Console project by clicking the Play/Debug button for each launch configuration.
Note: when the web browser launches at the root of the website, you may browse to the WeatherForecast Controller manually, e.g. https://localhost:5001/WeatherForecast
You should see each program pause at the breakpoints you set earlier.
Continue Running
Press the Play/Continue button to continue running while debugging. Observe the output in a web browser (for the Web API project) or the Terminal within VS Code (for the Web API project)
Optional: Run Multiple Projects
As a bonus, I have added a Compounds section to the launch.json file.
As promised, below is the initial release of the ASP .NET Core 3.1 A-Z ebook. This combines the 26 blog posts from the series of ASP .NET Core articles on this website.
You can find the complete ebook on GitHub using one of the links below:
The cover image was generated using the Canva mobile app
The 2020 eBook is still a work in progress 🙂
I’m using my Worker Service sample to auto-generate Word documents from each blog post by converting each article’s HTML into Word format using MariGold.OpenXHTML
After some tweaking, images have been manually resized using a Macro in the Word document. Automatic resizing doesn’t seem to work between HTML to Word conversions, but feel free to submit a Pull Request if you have suggestions on how to fix it.
Animated GIF images don’t work in the ebook, so a link to each original source has been included where they appear in a few chapters.
This is the twenty-sixth of a new series of posts on ASP .NET Core 3.1 for 2020. In this series, we’ve covered 26 topics over a span of 26 weeks from January through June 2020, titled ASP .NET Core A-Z! To differentiate from the 2019 series, the 2020 series mostly focused on a growing single codebase (NetLearner!) instead of new unrelated code snippets week.
Z is for Zero-Downtime* Web Apps for ASP .NET Core
If you’ve made it this far in this ASP .NET Core A-Z series, hopefully you’ve learned about many important topics related to ASP .NET Core web application development. As we wrap up this series with a look at tips and tricks to attempt zero-downtime, this last post itself has its own lettered A-F mini-series: Availability, Backup & Restore, CI/CD, Deployment Slots, EF Core Migrations and Feature Flags.
NOTE: While it may not be possible to get 100% availability 24/7/365, you can ensure a user-friendly experience free from (or at least with minimal) interruptions, by following a combination of the tips and tricks outlined below. This write-up is not meant to be a comprehensive guide. Rather, it is more of an outline with references that you can follow up on, for next steps.
Availability
To improve the availability of your ASP .NET Core web app running on Azure, consider running your app in multiple regions for HA (High Availability). To control traffic to/from your website, you may use Traffic Manager to direct web traffic to a standby/secondary region, in case the primary region is unavailable.
Consider the following 3 options when running a web app in multiple Azure regions. In these scenarios, the primary region is always active and the secondary region may be passive (as a hot or cold standby) or active. When both are active, web requests are load-balanced between the two regions.
Options
Primary Region
Secondary Region
A
Active
Passive, Hot Standby
B
Active
Passive, Cold Standby
C
Active
Active
For more information on achieving High Availability (HA) in multiple regions, check out the official docs at:
If you’re running your web app in a Virtual Machine (VM) instead of Azure App Service, you may also consider Availability Sets. This helps build redundancy in your Web App’s architecture, when you have 2 or more VMs in an Availability Set. For added resiliency, use Azure Load Balancer with your VMs to load-balance incoming traffic. As an alternative to Availability Sets, you may also use Availability Zones to counter any failures within a datacenter.
Backup & Restore
Azure’s App Service lets you back up and restore your web application, using the Azure Portal or with Azure CLI commands. Note that this requires your App Service to be in at least the Standard or Premium tier, as it is not available in the Free/Shared tiers. You can create backups on demand when you wish, or schedule your backups as needed. If your site goes down, you can quickly restore your last good backup to minimize downtime.
NOTE: You may use the new Snapshots feature to “automatically create perioidic restore points of your app”. However, this feature is only available in a Premium App Service Plan.
In addition to the app itself, the backup process also backs up the Web App’s configuration, file contents and the database connected to your app. Database types include SQL DB (aka SQL Server PaaS), MySQL and PostgreSQL. Note that these backups include a complete backup, and not incremental/delta backups.
Continuous Integration & Continuous Deployment
In the previous post, we covered CI/CD with YAML pipelines. Whether you have to fix an urgent bug quickly or just deploy a planned release, it’s important to have a proper CI/CD pipeline. This allows you to deploy new features and fixes quickly with minimal downtime.
Whether you’re deploying your Web App to App Service for the first time or the 100th time, it helps to test out your app before releasing to the public. Deployment slots make it easy to set up a Staging Slot, warm it up and swap it immediately with a Production Slot. Swapping a slot that has already been warmed up ahead of time will allow you to deploy the latest version of your Web App almost immediately.
Note that Deployment Slots are only available in Standard, Premium or Isolated App Service tiers, not in the Free/Shared tiers. You can combine Deployment Slots with your CI/CD pipelines to ensure that your automated deployments end up in the intended slots.
EF Core Migrations in Production
We covered EF Core Migrations in a previous post, which is one way of upgrading your database in various environments (including production). But wait, is it safe to run EF Core Migrations in a production environment? Even though you can use auto-generated EF Core migrations (written in C# or outputted as SQL Scripts), you may also modify your migrations for your needs.
I would highly recommend reading Jon P Smith‘s two-part series on “Handling Entity Framework Core database migrations in production”:
What you decide to do is up to you (and your team). I would suggest exploring the different options available to you, to ensure that you minimize any downtime for your users. For any non-breaking DB changes, you should be able to migrate your DB easily. However, your site may be down for maintenance for any breaking DB changes.
Feature Flags
Introduced by the Azure team, the Microsoft.FeatureManagement package allows you to add Feature Flags to your .NET application. This enables your web app to include new features that can easily be toggled for various audiences. This means that you could potentially test out new features by deploying them during off-peak times, but toggling them to become available via app configuration.
To install the package, you may use the following dotnet command:
By combining many/all of the above features, tips and tricks for your Web App deployments, you can release new features while minimizing/eliminating downtime. If you have any new suggestions, feel free to leave your comments.