Sign in

Senior Application Developer. MBA. I write blogs about .NET, Angular, JavaScript/TypeScript, Docker, AWS, DDD, and many others.
Photo by Drew Perales on Unsplash

Numbers and Counting

  • A bunch of apples are arranged in a line, but a peach is mixed in the line. If we count from the beginning, the peach is the fifth in line. If we count from the end, then the peach is the seventh in line. How many apples are there in the line? How many peaches are there?


As announced in the .NET 6 Preview 4 blog, .NET 6 will release an improvement to ASP.NET Core: minimal APIs for hosting and routing in web applications. With these streamlined APIs, we can build microservices and small HTTP APIs with much less ceremony.

This is exciting and let’s take a look at this new feature. Shall we?

In this article, I will first briefly describe the minimal APIs feature in .NET 6. To further demonstrate its use case, I will show you how to create a URL Shortener web app and containerize it using Docker step by step. …


In this post, I will first show you some basics of configuring Serilog for logging in .NET/ASP.NET applications. Then moving on to the topic of how to split or suppress logs. The source code can be found in my GitHub repository.

Serilog Configuration Basics

Serilog is a famous logging tool for .NET and ASP.NET applications. We can easily create a globally-shared logger using the following line of code.

Log.Logger = new LoggerConfiguration().CreateLogger();

The logger created in this way will have the same lifetime as that of our application. …


C# has a feature, String Interpolation, to format strings in a flexible and readable way. The following example demonstrates the way how we usually output a string when we have data beforehand then pass data to the template string.

gist link

On the other hand, the String Interpolation doesn’t work in some scenarios when we want to format certain strings following predefined templates. The string can be, for example, a log message, an alert, an Email template, and so on.

To solve this problem, we can use some NuGet packages (e.g., Nustache, Stubble, mustache#) to render templates by substituting parameters…


We do different levels of tests against controllers. When unit testing controller logic, the test only executes the action method itself without going through the framework’s request/response pipeline. In other words, the filter attributes (e.g., the Authorize attribute ), model binding, and middlewares do not affect unit tests for controllers. Thus, unit testing controller logic is quite similar to testing a regular class where we can mock dependencies and stage input values and verify outputs.

However, one special point is that controllers has an implicit dependency, ControllerContext, which is inherited from ControllerBase. …


Most background jobs are running behind the scene and are transparent to end-users, and admins usually don’t need to worry about the nitty-gritty of how the system automates tasks or when the system executes them. In some cases, product owners may know that there are background jobs supporting the application because they are involved in the requirement gathering phase of the application development lifecycle. However, as time passes or initial product owners transit away, corporate knowledge of background jobs starts to fade, unless the current product owners are tech-savvy users or they have detailed documentation at hand. …


We sometimes want to limit our application to only certain IP addresses or IP network ranges. For example, during beta testing, we prefer to only allow admins and preselected testers to access the new website. Besides blocking the whole application, we sometimes want to expose most APIs in an application but restrict a few API endpoints to a confined network so that sensitive data won’t be scrapped.

IP restrictions can be done at several levels to achieve security goals. As developers, we can properly guard our applications and API endpoints in the code so that they are available to trusted…


In this article, I will use a demo Web API application in ASP.NET Core to show you how to transmit files through an API endpoint. In the final HTML page, end users can left-click a hyperlink to download the file or right-click the link to choose “Save Link As” in the context menu and save the file.

The full solution can be found in my GitHub repository, which includes a web project for uploading/downloading files and an integration test project for testing controller methods.

Now let’s dive in.

Return a File in ASP.NET Core Web API

In ASP.NET Core, a Web API action method usually returns an ActionResult


ASP.NET Core uses configuration providers to read configuration key-value pairs from a variety of sources. You can read more about configuration in ASP.NET Core in its official documentation, which has covered tons of use cases in detail.

Recently, when I set a JSON array in the appsettings.json files in an ASP.NET Core project, the result of the final configuration data surprised me. The array did not behave the same as other JSON objects that could be overridden in an environment-specific appsettings.json file. Instead, the final array could have more elements than expected. After some googling, I found that there are…


Caching is a common technique to reduce the number of trips for fetching data that seldom changes. Thus we can take advantage of caching to boost our application’s performance. ASP.NET Core provides several caching libraries, including in-memory caching, distributed caching, and many others. Among these caching techniques, IMemoryCache, the simplest cache, is included in an ASP.NET Core web project by default and works natively with dependency injection.

There are many introductory articles talking about using the IMemoryCache to store data in the memory of the webserver. However, few of them have mentioned how to ensure the consistency of cached values…

Changhui Xu

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store