I recently needed to find a solution where I could run/schedule jobs within an ASP.NET website. The site is hosted where we do not have access to the server and cannot use Windows Services. Historically, it has been a problem running scheduled jobs within a web environment up until now. A hot new project called Hangfire has come up with a solution and is built with Katana, Microsofts’s OWIN implementation.
In this tutorial, I will cover the steps needed to run Hangfire within a project that does not use the ASP.NET MVC framework. I am using the Quick Start steps from Hangfire as a reference point.
- Installing Hangfire
- Add an OWIN Startup Class
- Configure Hangfire
- Add a job or recurring task
- Using the Dashboard
Installing Hangfire
Use Nuget and install Hangfire (comes with SQL Server Storage) in your project. You could also use the Package Manager Console.
PM> Install-Package Hangfire
Add an OWIN Startup Class
Create a Startup.cs file in the root of your website and add the following:
using Hangfire; using Hangfire.SqlServer; using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(YourNamespace.Startup))] namespace YourNamespace { public partial class Startup { public void Configuration(IAppBuilder app) { Hangfire.ConfigureHangfire(app); Hangfire.InitializeJobs(); } } }
Notice the [assembly: OwinStartup(typeof(YourNamespace.Startup))] line. This hooks up YourNamespace.Startup to OWIN and the IIS integrated pipeline.
Configure Hangfire
Create another file called Hangfire.cs. It’s not required but I did it to centralize my custom Hangfire code. Here is a sample of what I put in this file:
using Hangfire; using Hangfire.SqlServer; using Hangfire.Dashboard; using Microsoft.Owin; using Owin; namespace YourNamespace { public class Hangfire { public static void ConfigureHangfire(IAppBuilder app) { app.UseHangfire(config => { config.UseSqlServerStorage("HangFireDB"); config.UseServer(); config.UseAuthorizationFilters(); //allow all users to access the dashboard }); } public static void InitializeJobs() { RecurringJob.AddOrUpdate<AccountStatusJob>(j => j.Execute(), "0 1,21 * * *"); } } }
The Job or Recurring Task
In the example above, I created a method called InitializeJobs(). This is where you create the job/task(s) using CRON expressions. Keep in mind that Hangfire uses UTC for its time scheduling so base your times accordingly.
I created another class called AccountStatusJob with a static method called Execute() which is what the job will call when it runs. This particular job has a CRON expression setting it to run everyday at 2pm and 6pm Pacific time (converted to UTC). Here is a nice expression builder from ABunchOfUtils.com to help you along.
Using the Dashboard
The Dashboard is really handy! This is where you can see the jobs you have configured, when they ran, when they will run again and you can trigger or delete them! In order to use the Dashboard, you need to navigate to it like so:
http://<yoursite>/Hangfire
The Dashboard is setup to run when you are accessing it locally (such as localhost) but when it is in production it requires authorization. You need to use Nuget or the Package Manager Console and install Hangfire Dashboard Authorization Filters.
PM>Install-Package Hangfire.Dashboard.Authorization
What I did to get around this security and not have to implement any ASP.NET Identity was add the following line in the example above:
config.UseAuthorizationFilters();
Read more about the Dashboard authorization.
The days of web forms are quickly passing and ASP.NET MVC is running strong. What a great time to find solutions to run the new with the old.