Why I moved my logic from WebJobs to WebHooks

At some point you might want to run some task in the background. WebJobs allow you to do this. It works perfectly until you end up changing the DbContext.
Then depending on your scenario you right-click publish your WebJob or have a CI/CD task to redeploy.

The Problem

It becomes too much work to remember to update every WebJob even if you have a CI/CD task.

The Solution

Decouple the database from the WebJob, implement a WebHook receiver and have the logic take place there.

The How

Nuget Packages

The first step is installing the Generic Receiver package into your ASP.NET project.
Microsoft.AspNet.WebHooks.Receivers.Generic

WebHook routes are configured in WebApiConfig, but if you're doing this in a MVC project, then don't forget this package.
Microsoft.AspNet.WebApi.WebHost
Also to add this line of code to your Global.asax file.
GlobalConfiguration.Configure(WebApiConfig.Register);
You can copy the WebApiConfig.cs file from the example on GitHub.


Config Setup

To your WebApiConfig.cs add this line.
config.InitializeReceiveGenericJsonWebHooks();

In your Web.config add this app setting. "taskname" is the context identifier used in your receiver.
key="MSWebHookReceiverSecretGenericJson" value="taskname=forwebhookmysupersecrettousefor1"


Receiver Setup

Create a WebHook Handler in your Controller folder that inherits from WebHookHandler, your Handler should look like below.

  public class ExampleHandler : WebHookHandler
{
    public ExampleHandler()
    {
        this.Receiver = "genericjson";
    }

    public async override Task ExecuteAsync(string generator, WebHookHandlerContext context)
    {

        switch (context.Id)
        {
            case "taskname":
                break;
        }

    }

}

Real World Use

I have a WebJob that runs periodically which POSTs to my WebHook receiver.
You can have multiple context identifiers, just remember each will need a secret. The switch statement checks the context id and the logic is performed for it.

I prefer this since the WebJob is decoupled from the Db and the DbContext is in sync with the WebApp also the logic is kept and maintained in one place.
An example project is on GitHub.