Building a .NET Core 8 API with Hangfire and SQL Server
Table of contents
- Prerequisites
- Step 1: Setting Up the Project
- Step 2: Adding Hangfire to the Project
- Step 3: Adding a JobController
- Step 4: Configuring SQL Server with Docker or a Local Instance
- Step 5: Connecting to SQL Server
- Step 6: Configuring launchSettings.json
- Step 7: Running and Testing the Application
- Step 8: Using an HTTP Client to Test Endpoints
- Conclusion
In this tutorial, we'll guide you through creating a .NET Core 8 API project that leverages Hangfire for background processing and uses SQL Server for job storage. Hangfire is a powerful library that allows you to run background jobs, schedule tasks, and handle delayed or recurring tasks with ease. It's particularly useful for use cases such as:
Sending Emails: Automatically sending confirmation, notification, or reminder emails in the background without delaying the main thread.
Data Processing: Running intensive data processing tasks asynchronously, such as generating reports, processing files, or handling complex calculations.
Cleanup Tasks: Scheduling regular cleanup jobs to remove outdated or unnecessary data from your database or storage.
Notification Systems: Triggering push notifications, SMS, or other alerts at specified times or based on specific conditions.
Maintenance Jobs: Automating routine maintenance tasks like database backups, log rotation, or system health checks.
You can find the complete source code for this project on GitHub. By the end of this tutorial, you’ll have a robust API capable of handling these types of background tasks, along with a Hangfire dashboard to monitor job execution.
Prerequisites
Before we get started, make sure you have the following installed:
A text editor or IDE like Visual Studio Code or Visual Studio
SQL Server Management Studio (SSMS) or a similar SQL management tool
Step 1: Setting Up the Project
Begin by creating a new .NET Core 8 Web API project:
dotnet new webapi -n HangfireExample
cd HangfireExample
Step 2: Adding Hangfire to the Project
Hangfire is a library that simplifies background job processing in .NET applications. To add Hangfire to your project, install the necessary NuGet packages:
dotnet add package Hangfire
dotnet add package Hangfire.SqlServer
Next, configure Hangfire in your Program.cs
file:
using Hangfire;
using Hangfire.SqlServer;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Add Hangfire services.
builder.Services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(builder.Configuration.GetConnectionString("HangfireConnection"), new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
UsePageLocksOnDequeue = true,
DisableGlobalLocks = true
}));
// Add the processing server as IHostedService
builder.Services.AddHangfireServer();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Use Hangfire dashboard
app.UseHangfireDashboard();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.Run();
Step 3: Adding a JobController
To demonstrate Hangfire in action, let's create a simple controller that enqueues a background job:
using Hangfire;
using Microsoft.AspNetCore.Mvc;
using System;
namespace HangfireExample.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class JobController : ControllerBase
{
private readonly IBackgroundJobClient _backgroundJobClient;
public JobController(IBackgroundJobClient backgroundJobClient)
{
_backgroundJobClient = backgroundJobClient;
}
[HttpPost("enqueue")]
public IActionResult EnqueueJob()
{
_backgroundJobClient.Enqueue(() => Console.WriteLine("Background job executed in .NET Core 8!"));
return Ok("Job has been enqueued.");
}
[HttpPost("schedule")]
public IActionResult ScheduleJob()
{
_backgroundJobClient.Schedule(() => Console.WriteLine("Scheduled job executed in .NET Core 8!"), TimeSpan.FromMinutes(1));
return Ok("Job has been scheduled.");
}
}
}
Step 4: Configuring SQL Server with Docker or a Local Instance
To persist Hangfire jobs, we need a SQL Server database. You have two options here: set up SQL Server using Docker or connect to an existing local SQL Server instance.
Option 1: Using Docker
If you want to use Docker to run SQL Server, create a docker-compose.yml
file:
version: '3.8'
services:
sqlserver:
image: mcr.microsoft.com/mssql/server:latest
container_name: sqlserver
environment:
- SA_PASSWORD=YourStrong!Passw0rd
- ACCEPT_EULA=Y
ports:
- "1433:1433"
volumes:
- sqlserverdata:/var/opt/mssql
networks:
- sqlnetwork
volumes:
sqlserverdata:
networks:
sqlnetwork:
Run the Docker container:
docker-compose up -d
Option 2: Using a Local SQL Server Instance
If you already have SQL Server installed on your local machine, you can skip the Docker setup. Simply ensure that your SQL Server instance is running and accessible.
Connecting to the SQL Server Database (For both option)
The following steps apply whether you're using Docker or a local SQL Server instance:
Open SQL Server Management Studio (SSMS) or any other SQL management tool.
Create a new database named
Hangfire
.Visualize the Database and Tables:
Once Hangfire is configured and your application runs for the first time, Hangfire will automatically create the necessary tables in the
Hangfire
database.The tables will include ones for job storage, processing states, and more. They will look something like this:
Step 5: Connecting to SQL Server
Add your connection string in appsettings.json
:
{
"ConnectionStrings": {
"HangfireConnection": "Server=localhost,1433;Database=Hangfire;User Id=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=True;"
}
}
Step 6: Configuring launchSettings.json
In your .NET Core 8
project, navigate to the Properties
folder, and locate the launchSettings.json
file. If it doesn’t exist, you can create it.
Here’s a typical launchSettings.json
configuration for the project:
{
"profiles": {
"HangfireExample": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7002;http://localhost:7001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": false,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"use64Bit": true,
"sslPort": 44319
}
}
}
Step 7: Running and Testing the Application
Run your application:
dotnet run
Once the application is running, you can enqueue and schedule background jobs by sending POST requests to your API. Here’s how you can test these endpoints using an HTTP client:
Enqueue a Job: Send a POST request to
http://localhost:7002/api/job/enqueue
.Schedule a Job: Send a POST request to
http://localhost:7002/api/job/schedule
.
Additionally, you can monitor and manage your background jobs using the Hangfire Dashboard, which is accessible at http://localhost:7002/hangfire
.
Step 8: Using an HTTP Client to Test Endpoints
You can create an .http
file to easily test the API endpoints. Alternatively, you can use postman client too. Here’s an example HangfireExample.http
file:
@HangfireExample_HostAddress = http://localhost:7002
# Enqueue a Background Job
POST {{HangfireExample_HostAddress}}/api/job/enqueue
Content-Type: application/json
###
# Schedule a Background Job
POST {{HangfireExample_HostAddress}}/api/job/schedule
Content-Type: application/json
###
# Get Hangfire Dashboard (if exposed for testing)
GET {{HangfireExample_HostAddress}}/hangfire
Accept: text/html
You can use this .http
file in a REST client like Visual Studio Code's REST Client extension to quickly send requests to your API.
Conclusion
In this tutorial, we built a .NET Core 8 API that integrates Hangfire for handling background jobs. We also set up SQL Server using Docker to persist these jobs and used the Hangfire Dashboard to monitor and manage them.
This setup is highly versatile and can be extended to meet your specific requirements, whether it's adding more complex background jobs or deploying your API in a production environment. Happy coding!
Subscribe to my newsletter
Read articles from Imran Khan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Imran Khan
Imran Khan
As a Senior Software Engineer with over five years of experience in developing enterprise applications and SaaS solutions, I specialize in full-stack development with a strong foundation in ASP.NET Core, SQL, ReactJS, and Node.js. My expertise lies in designing scalable, high-performance systems, managing complex databases, and implementing microservices. I've successfully delivered projects across diverse domains, from financial applications to human resource systems, ensuring quality and efficiency through agile practices. I thrive in collaborative environments, continuously striving to enhance software performance and drive innovation.