Using Hangfire with Sitefinity

Using Hangfire with Sitefinity

Posted on October 17, 2018 0 Comments
Using Hangfire with Sitefinity_870x450

Sitefinity has great built-in options for scheduling your background tasks, but for those times you need more, it’s also easy to integrate external tools. Here’s how you can improve your task scheduling in Sitefinity with Hangfire.

Problem—Run and Manage Background Tasks in Sitefinity

As a web developer, you may face different scenarios which require using scheduled background tasks. The scenarios may vary from obtaining data from external or internal source (e.g. Database, CRM, ERP etc.), modifying it and storing it again to just triggering some custom logic every minute, day, week etc.

Possible Solutions

  • Sitefinity ships with its own version of scheduling mechanism using SchedulingManager. It is extensible and can be used in a lot of different scenarios.
  • Another option is to use a very popular background job processing tool called Hangfire. It has a built-in user interface for managing the scheduled tasks.

Sitefinity Built-in Scheduler vs Hangfire

First let's see what is common for both approaches. Both:

  • Do not block the user interface (it runs in a separate thread)
  • Can be run on NLB environments and tasks will run on different servers
  • Use a database to store the task data, so the information will be preserved on application restart
  • Use an API for managing background jobs

Now let's see the differences.

 Sitefinity Built-in Scheduler  Hangfire
 
  • No external dependencies on third party libraries.
  • No additional licenses.
  • No extra charge
  • Ships with the product from its beginning.
 
  • It is a mature software. The first version is from the end of 2013 and it is actively developed.
  • It has a user interface—built-in dashboard which eases jobs maintainability.
  • It comes with predefined job types to easily configure custom jobs.
  • Supports CRON syntax
  • Free and paid versions available

 

Given this, it is recommended to use the built-in Sitefinity Scheduler for small numbers or similar types of scheduled tasks, when you don’t really require a management UI for them.

Hangfire is convenient when you need advanced scheduling configuration (e.g. CRON syntax) and have to manage the jobs using UI.

Now let's see how to integrate Hangfire in Sitefinity. There are 2 simple steps:

  • Install Hangfire packages in your solution
  • Configure Hangfire in your Sitefinity Project

Installing Hangfire in Sitefinity

In order to use Hangfire with your Sitefinity application you need to install the Hangfire NuGet package and all its required dependencies:

  1. Open your Sitefinity application project in Visual Studio.
  2. Navigate to Tools > NuGet Package Manager and select Package Manager Console.
  3. Execute the following command:
    Install-Package Hangfire

    NOTE: Sitefinity 11 references Owin and Newtonsoft.Json versions which are higher than the default ones used by Hangfire. Make sure to update all NuGet packages so they correspond to the versions referenced by Sitefinity. To do this you can execute the following commands in the NuGet Package manager console:
    Update-Package Owin -Version 3.1.0
    Update-Package Owin.Host.Systemweb -Version 3.1.0
    Update-Package NewtonSoft.Json -Version 9.0.1

Once you have installed the needed NuGet packages you can proceed with configuring Sitefinity to use Hangfire.

Configuring Hangfire in Sitefinity

Hangfire is based on OWIN middleware and Sitefinity provides a clean and easy integration.

Create Custom Startup Class to Register Hangfire

The first step is to create a class and name it Startup (if such a class already exists it can be used). This class is used as an entry point by OWIN which looks for a Configure() method to execute upon the application startup.

There is already a great article about integrating OWIN in Sitefinity which can be found here.

using Hangfire;
using Microsoft.Owin;
using Owin;
using System;
using Telerik.Sitefinity.Abstractions;
using Telerik.Sitefinity.Owin;
   
namespace SitefinityWebApp
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Registers the default Sitefinity middlewares
            app.UseSitefinityMiddleware();
  
            // Configures the SQL Server connection for Hangfire
            GlobalConfiguration.Configuration.UseSqlServerStorage(connectionStringName);
  
            // Registers Hangfire background job server
            app.UseHangfireServer();
  
            // Registers Hangfire dashboard UI under the specified path
            // and provides an authorization filter
            app.UseHangfireDashboard("/hangfire", new DashboardOptions
            {
                Authorization = new[] { new SitefinityAuthorizationFilter() }
            });
  
            // Creates a recurring background job
            RecurringJob.AddOrUpdate(() => Log.Write("Long-running job executed by Hangfire.", ConfigurationPolicy.Trace), "* * * * *");
  
            // Creates a scheduled background job
            BackgroundJob.Schedule(() => Log.Write("Scheduled job executed by Hangfire.", ConfigurationPolicy.Trace), TimeSpan.FromMinutes(5));
        }
  
        private string connectionStringName = "Hangfire";
    }
}
 

The code snippet above attaches Sitefinity middleware to the app. This is needed in order to turn on Sitefinity OWIN capabilities. Then we register the SQL Server storage by passing the name of the connection string which is used for persisting the background job data. For UI visualization the Hangfire dashboard middleware is also registered. To secure the dashboard, we set an authorization option which prevents unauthorized access. Finally, there are two background jobs created:

  • Recurring job - triggered every minute
  • Background job - triggered only once, 5 minutes after application start

Configure Connection String

The connection string for Hangfire can be added in the web.config file:

<connectionStrings>
  <add connectionString="data source=.\SQLSERVER;Integrated Security=SSPI;initial catalog=SitefinityDB" name="Hangfire" />
</connectionStrings>


In our case we are using the same database were the Sitefinity data is persisted.

Configure Custom Startup Class in Your Application

In addition to creating a Startup class it is also important to add an entry in the web.config file to make your application aware of the OWIN entry point:

<add key="owin:appStartup" value="SitefinityWebApp.Startup" />


Securing the Hangfire Dashboard

Lastly, we need to secure the Hangfire dashboard so that only users with administrative rights can view it. Failing to do so can pose a serious security threat to our web application. Fortunately, Hangfire provides us with an easy way of creating an authorization filter to accomplish just that.

using Hangfire.Dashboard;
using Telerik.Sitefinity.Security.Claims;
  
namespace SitefinityWebApp
{
    internal class SitefinityAuthorizationFilter : IDashboardAuthorizationFilter
    {
        public bool Authorize(DashboardContext context)
        {
            // Retrieve the Sitefinity identity of the current users
            var currentIdentity = ClaimsManager.GetCurrentIdentity();
  
            // Checks whether the Sitefinity identity has unrestricted access
            return currentIdentity != null && currentIdentity.IsUnrestricted;
        }
    }
}

 

In the code snippet above we create a SitefinityAuthorizationFilter class by implementing the IDashboardAuthorizationFilter interface. Next, we implement the Authorize() method in which the current user’s identity is retrieved by calling the ClaimsManager.GetCurrentIdentity() method. Finally, we return the IsUnrestricted property which checks whether the Sitefinity identity of the user has unrestricted access to the website (e.g. if the user is an administrator).

hangfire-dashboard

How Does it Work?

Let's take a look under the hood of Hangfire. The picture below shows the lifecycle of a job.

Hangfire and Sitefinity

More Hangfire Configurations with IoC

In advanced software architecture, you may want to use IoC containers such as ObjectFactory in Sitefinity. Hangfire uses JobActivator to instantiate the target types and allows you to implement a custom job activator, like for example ObjectFactoryJobActivator. More information about how to implement it can be found here.

Conclusion

Sitefinity provides developers with an easy and simple way for integrating any pluggable middleware that adheres to the OWIN concept.

In addition to Sitefinity’s built-in capabilities, integrating Hangfire into Sitefinity is easy and makes it possible to easily extend and modify the job scheduler.

Want to learn more about what Progress Sitefinity can do? Feel free to request a demo today. 

nader_dabour

Nader Dabour

Nader Dabour is a senior developer at Progress. He has been with the Sitefinity team since 2014 and has worked on various domains including technical documentation, infrastructure, bug fixing, development of internal tools, product features and public web portals. He is passionate about Sitefinity and all things web.

Comments

Comments are disabled in preview mode.
Topics

Sitefinity Training and Certification Now Available.

Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.

Learn More
Latest Stories
in Your Inbox

Subscribe to get all the news, info and tutorials you need to build better business apps and sites

Loading animation