Send Mail Using HangFire In .Net Core 6

In this article, we will learn about Hangfire and how to integrate it and send a mail with the help of it in the .Net core 6 Application.

Running jobs in the background such as data processing, email reminders, and email queue is a common programming task we face regularly. And running these jobs correctly without messing up your code isn’t easy, but it’s also not difficult. I have worked with Windows services to schedule different tasks within my C# application. Then I found Hangfire, an amazing library.

What is Hangfire?

Hangfire is an open-source library that helps us schedule and executes background jobs such as data processing, email reminders, and processing SMS queues and email queues in .NET applications. It is a highly flexible library offering various features needed to make the job scheduling task. You’ll be able to create a simple background process inside the same application without creating separate applications.

Hangfire Database Schema:

Hangfire checks if you have an associated Hangfire Schema in your database when you start your ASP.NET Core Application for that period. Otherwise, it will generate a slew of tables for you. This is how your database would seem.

Hangfire Workflow:

The Hangfire client produces the job and puts it in the database when we specify our task in the code and execute the relevant Hangfire method to create it. The control is then returned to the program, allowing the main thread to resume its task.
When work is fetched from storage, the server retrieves it and creates a background thread to process it.

Prerequisites

Let us start with an example.

Let’s create a new ASP.NET Core Web API project.

Then click on the Next button and give the project name as shown below.

Then select a Framework and then click on Create button.

Once the project is created open and install the following package for hangfire.

Install-Package HangFire

Now create HangfireDbContext and add the following line to it.

using Microsoft.EntityFrameworkCore;

namespace SendMailHangFire.AppDbContext
{
    public class HangfireDbContext : DbContext
    {
        public HangfireDbContext(DbContextOptions options) : base(options)
        {
        }
    }
}

Then Open your appsettings.json and add your connection string to it.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    "myconn": "Your Connection String"
  },
  "AllowedHosts": "*",
  "CronTime": "*/5 * * * *",//corn time specified at what time you want to run your task.
//Email credentials for sending email
  "EmailConfiguration": {
    "email": "Sender@gmail.com",
    "password": "password"
  }
}

The next step is to open the  Startup.cs file and Inside the configure services please add the hangfire services as shown below.

using Hangfire;
using Microsoft.EntityFrameworkCore;
using SendMailHangFire.AppDbContext;
using SendMailHangFire.Services;

var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
#region Configure Connection String
builder.Services.AddDbContext<HangfireDbContext>(item => item.UseSqlServer(builder.Configuration.GetConnectionString("myconn")));
#endregion

#region Configure Hangfire
builder.Services.AddHangfire(c => c.UseSqlServerStorage(builder.Configuration.GetConnectionString("myconn")));
GlobalConfiguration.Configuration.UseSqlServerStorage(builder.Configuration.GetConnectionString("myconn")).WithJobExpirationTimeout(TimeSpan.FromDays(7));
#endregion

builder.Services.AddTransient<ISendMailServices, SendMailServices>();

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();
app.UseStaticFiles();
app.MapControllers();

app.Run();

Then apply the following command in the package manager console to create a table.

Add-Migration initial
Update-database

And you see the table create by hangfire in your database as shown above image.

Then create SendMailController in your controller folder and paste the below code into it.

using Microsoft.AspNetCore.Mvc;
using SendMailHangFire.Model;
using SendMailHangFire.Services;

namespace SendMailHangFire.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class SendMailController : ControllerBase
    {
        private ISendMailServices _sendMailServices;

        public SendMailController(ISendMailServices sendMailServices)
        {
            _sendMailServices = sendMailServices;
        }

        [HttpPost("SendEmail")]
        public async Task<ResponseVM> SendEmail() => await _sendMailServices.SendEmail();
    }
}

Then create the ISendMailServices interface and paste the below code into it.

using SendMailHangFire.Model;

namespace SendMailHangFire.Services
{
    public interface ISendMailServices
    {
        Task<ResponseVM> SendEmail();
    }
}

Then create SendMailServices class and paste the below code into it.

using SendMailHangFire.Model;
using System.Globalization;
using System.Net;
using System.Net.Mail;

namespace SendMailHangFire.Services
{
    public class SendMailServices : ISendMailServices
    {
        private readonly IWebHostEnvironment _webHostEnvironment;
        private readonly IConfiguration _configuration;
        public SendMailServices(IWebHostEnvironment webHostEnvironment, IConfiguration configuration)
        {
            _webHostEnvironment = webHostEnvironment;
            _configuration = configuration;
        }
        public async Task<ResponseVM> SendEmail()
        {
            //Email
            var message = EMailTemplate("WelcomeEmail");
            message = message.Replace("UserName", "User");
            message = message.Replace("Title", "Hangfire Test Mail");
            message = message.Replace("message", "Welcome To The Code Hubs");
            await SendEmailAsync("receiver@gmail.com", "Test subject", message);
            //End Email
            return new ResponseVM
            {
                message = "message send successfully"
            };
        }
        public string EMailTemplate(string template)
        {
            var path = Path.Combine(_webHostEnvironment.WebRootPath, "EmailTemplate.html");
            string body = System.IO.File.ReadAllText(path);
            return body.ToString();
        }
        public async Task SendEmailAsync(string email, string subject, string message)
        {
            var _email = _configuration["EmailConfiguration:email"];
            var _epass = _configuration["EmailConfiguration:password"];
            var _dispName = "Test Mail";

            MailMessage myMessage = new MailMessage();
            myMessage.To.Add(email);
            myMessage.From = new MailAddress(_email, _dispName);
            myMessage.Subject = subject;
            myMessage.Body = message;
            myMessage.IsBodyHtml = true;

            using (SmtpClient smtp = new SmtpClient("smtp.gmail.com", 587))
            {
                smtp.Credentials = new NetworkCredential(_email, _epass);
                smtp.EnableSsl = true;
                await smtp.SendMailAsync(myMessage);
            }
        }
    }
}

Create ResponseVM class in a Model folder and paste the below code into it.

namespace SendMailHangFire.Model
{
    public class ResponseVM
    {
        public string message { get; set; }
        public dynamic data { get; set; }
    }
}

Add the EmailTemplate.html template to your wwwroot folder.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <table>

        <tr>
            <td>
                <div style="border-top:3px solid #22BCE5"> </div>
                <span style="font-family:Arial;font-size:10pt">
                    Hello <b>UserName</b>,<br /><br />
                    <a style="color:#22BCE5" href="{Url}">Title</a><br />
                    message
                    <br /><br />
                    Thanks<br />
                 <strong>Shaikh Hafeezjaha</strong>
                </span>
            </td>
        </tr>
    </table>
</body>
</html>

Now test your API with help of postman that it’s working fine or note.


As you can see in the above image my API is working fine. Now I am going to schedule my API to call it every 5 min with the help of hangfire.

For this, you have to just add a few lines in your program.cs file as shown below.

IConfiguration configuration = app.Configuration;
IWebHostEnvironment environment = app.Environment;

#region Configure hangfire dashoard and call send mail service function
SendMailServices _sendMailServices = new SendMailServices(environment, configuration);
//app.UseHangfireServer();
app.UseHangfireDashboard("/myJobDashboard");
RecurringJob.AddOrUpdate("Send Mail : Runs Every 5 Min", () => _sendMailServices.SendEmail(), builder.Configuration["CronTime"]);
#endregion

Types of Background Jobs/Tasks

  •   Fire and Forget
  •   Delayed
  •   Periodic and Scheduled
  •   Continuations

Fire and Forget: As the name implies, Fir and Forget jobs are only run once after they are created. For example, sending a welcome email when users signup.

Delayed: Delayed tasks are similar to fire and forget, except instead of executing as soon as the action is taken, we set a time for the background job to run. For instance, suppose we want to send a user a voucher or discount 5 hours after they joined up.
Recurring: These jobs are performed periodically based on a schedule, for example, generating marketing emails or generating invoices.
Continuations: Continuations are executed when their parent’s job has been finished.

That’s it.

Output:

Also, Check How To Resolve the Request Body Too Large Error In .Net Core 6

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories