Earn More by Sharing What You Love
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Tim Corey
23m 30s
Developing and testing RESTful APIs in C# using ASP.NET Core is a practical skill for any modern backend developer. In his tutorial video on "Adding Health Checks - Building a Sample API in C# Course", Tim Corey walks through building a sample API with integrated health checks. This article, based solely on Tim's transcript, explains the entire process step by step, covering key points like the use of public async Task, int id, var app, and other HTTP request methods.
Let's take a deeper look at how Tim Corey sets up health checks in a C# API project using Visual Studio Code.
Tim explains that a sample API is a powerful tool when learning web development. It allows developers to simulate API calls using GET, POST, PUT, and DELETE methods, with appropriate request data and status codes. The API Tim builds supports:
Tim opens the project in Visual Studio Code and right-clicks on Dependencies to manage NuGet packages. He searches for and installs the AspNetCore.HealthChecks.UI.Client package. This enables the app to support two types of health checks.
Tim adds a new folder named HealthChecks inside the API project folder. Here, he creates multiple classes implementing the IHealthCheck interface, each representing a different status: healthy, degraded, unhealthy, and random.
This class returns a HealthCheckResult.Healthy using a public async Task<HealthCheckResult> implementation:
return Task.FromResult(HealthCheckResult.Healthy("This is a test healthy service."));Return Task.FromResult(HealthCheckResult.Healthy("This is a test healthy service."))This simulates a healthy status, useful for testing how your front end handles a stable service.
return Task.FromResult(HealthCheckResult.Degraded("This is a test degraded service."));Return Task.FromResult(HealthCheckResult.Degraded("This is a test degraded service."))This check returns a degraded service response. It's a simple way to simulate partial failure or performance issues.
return Task.FromResult(HealthCheckResult.Unhealthy("This is a test unhealthy service."));Return Task.FromResult(HealthCheckResult.Unhealthy("This is a test unhealthy service."))This mimics a failed service, simulating cases where you would expect a 500 HTTP status code or return NotFound().
This health check uses a random integer to simulate one of the three states:
int randomResult = Random.Shared.Next(1, 4);
return randomResult switch
{
1 => Task.FromResult(HealthCheckResult.Healthy("This is a test random service.")),
2 => Task.FromResult(HealthCheckResult.Degraded("This is a test random service.")),
3 => Task.FromResult(HealthCheckResult.Unhealthy("This is a test random service.")),
_ => Task.FromResult(HealthCheckResult.Healthy("This is a test random service."))
};Dim randomResult As Integer = Random.Shared.Next(1, 4)
Return randomResult Select Case
Case 1
Task.FromResult(HealthCheckResult.Healthy("This is a test random service."))
Case 2
Task.FromResult(HealthCheckResult.Degraded("This is a test random service."))
Case 3
Task.FromResult(HealthCheckResult.Unhealthy("This is a test random service."))
Case Else
Task.FromResult(HealthCheckResult.Healthy("This is a test random service."))
End SelectTim emphasizes this is useful for testing behavior under variable conditions.
Tim adds a new static class HealthChecksConfig.cs in the Startup or configuration folder. This class includes two static methods:
services.AddHealthChecks()
.AddCheck<RandomHealthCheck>("random", tags: new[] { "random" })
.AddCheck<HealthyHealthCheck>("healthy", tags: new[] { "healthy" })
.AddCheck<DegradedHealthCheck>("degraded", tags: new[] { "degraded" })
.AddCheck<UnhealthyHealthCheck>("unhealthy", tags: new[] { "unhealthy" });services.AddHealthChecks() _
.AddCheck(Of RandomHealthCheck)("random", tags:=New String() {"random"}) _
.AddCheck(Of HealthyHealthCheck)("healthy", tags:=New String() {"healthy"}) _
.AddCheck(Of DegradedHealthCheck)("degraded", tags:=New String() {"degraded"}) _
.AddCheck(Of UnhealthyHealthCheck)("unhealthy", tags:=New String() {"unhealthy"})This registers all the health checks for dependency injection in the services container of ASP.NET Core.
app.MapHealthChecks("/health");app.MapHealthChecks("/health")This creates a single endpoint /health that evaluates all services together. If any are unhealthy, the entire check returns unhealthy.
To test individual components, Tim maps each health check by tag:
app.MapHealthChecks("/health/healthy", new HealthCheckOptions {
Predicate = x => x.Tags.Contains("healthy")
});app.MapHealthChecks("/health/healthy", New HealthCheckOptions With {
.Predicate = Function(x) x.Tags.Contains("healthy")
})He repeats this for /health/degraded, /health/unhealthy, and /health/random. Each allows developers to test specific behaviors and how their frontend reacts to them.
When visiting /health/random, the output changes between "healthy", "degraded", and "unhealthy" based on the random result.
Tim enhances the endpoints by enabling a UI response for each health check route. This provides a JSON output:
app.MapHealthChecks("/healthui", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});app.MapHealthChecks("/healthui", New HealthCheckOptions With {
.ResponseWriter = AddressOf UIResponseWriter.WriteHealthCheckUIResponse
})This allows inspection of each health check with data like duration, tags, and status. Tim then creates UI versions for each health endpoint:
Each responds with a detailed JSON format, ideal for RESTful APIs and testing from mobile devices or web pages.
Tim highlights that even with these features, Program.cs is still only 21 lines long. He attributes this to:
He also emphasizes how useful this sample API is in production environments for simulating latency or faults before deployment.
"We can do a lot more testing with this API beyond just making GET calls to it," Tim concludes.
Tim previews the next lesson where he'll add simulated slowdowns (e.g., 5-second delays) and errors like return NotFound() or return BadRequest() to test API behavior even further.
In this video tutorial, Tim Corey methodically walks through building a minimal API with integrated health checks using ASP.NET Core. Key components include:
This approach makes it easier to validate REST APIs, simulate failures, and strengthen web applications for both development and production environments.
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!
Join our newsletter, you’ll get exclusive access on article updates. We value your privacy