Recently, I needed to synchronize data from an external database for a solution running in a Web App using the MySQL in-app database. My first step was to create an OData REST API interface on top of the external DB, which needed to be called once in a while. I thought that an Azure Webservice WebJob might be a good solution to do this task while keeping expenses down. Then I would have the DB, the service, and WebJob on the same unit, which would keep my expenses and complexity down. If, in the future, there would be no longer be a need to sync data we could just stop the WebJob.
We chose to create a project that is configured to deploy automatically as a WebJob when deploying a web project in the same solution. I used this option because the WebJob should run in the same web app in which the related web application is running. We are kind of stuck using the .NET Framework since XAF, which the app is developed with, has not yet been fully ported to .NET Core.
Since I needed this to be a scheduled task – even though we had not yet decided how often it would run – we wanted it to run with a timer and not triggers from other systems. The data synchronization runs seamlessly in the background without any end-user interference.
Prerequisites
Ensure that your project is set to use .NET version 4.7.1 or higher.
Make sure that the Web App your WebJob is going to run on, in Azure Portal, is set to “always-on”.
So, Let’s Begin
Right click on “add” on your releated web application in visual studio and select Add -> New Azure WebJob Project
Add the Microsoft.Azure.WebJobs.Extension NuGet package version 4.0.1 to the project. The problems I had with getting this project to work was actually very version related. So if you read this post recently, I recommend you use the versions I’ve posted here.
Replace your main function in the autogenerated program.cs with this:
static async Task Main()
{
var builder = new HostBuilder();
builder.UseEnvironment("development");
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices()
.AddTimers();
});
var host = builder.Build();
using (host)
{
await host.RunAsync();
}
}
Replace your Functions class in the file functions.cs with this:
public class Functions
{
public async Task TimerTriggerOperation([TimerTrigger("0 */5 * * * *", RunOnStartup = true)] TimerInfo timerInfo,ILogger logger, CancellationToken cancellationToken)
{
// To some work...
await Task.Delay(100, cancellationToken);
string scheduleStatus = string.Format("Status: Last='{0}', Next='{1}', IsPastDue={2}",
timerInfo.ScheduleStatus.Last, timerInfo.ScheduleStatus.Next, timerInfo.IsPastDue);
logger.LogInformation(scheduleStatus);
}
}
Place an appsettings.json file in the root of your application, with this content in it (you have to do this you cannot use the app.config, there is a bug in the extensions package).
{
"ConnectionStrings": {
"AzureWebJobsDashboard": "DefaultEndpointsProtocol=https;AccountName=Accounting;AccountKey=PeQPzZiEYikTbJxN4Lk6b/MhGr34yPQondugx/o/XFJ63n04gdNYIglZG+L+jT6J5QYnwTiXl6wWKYT2dCJ1yw==;EndpointSuffix=core.windows.net",
"AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=Accounting;AccountKey=PeQPzZiEYikTbJxN4Lk6b/MhsddsLr34yOQondugx/o/XFJ63n04gdNYIglZG+L+jT6J5QYnwTiXl6wWKYT2dCJ1yw==;EndpointSuffix=core.windows.net"
}
}
Voila!!! Now you should be ready to go. Next, we will look into deploying this to the WebApp through an Azure DevOps pipeline.
Comments