In a similar construction as the previous blog about creating webjobs for the .NET Framework, we needed a Sync WebJob now for the same kind of solution except that the Web App was a .NET 5.0 blazor solution. Therefore we needed to create an Azure WebJob which could run alongside this. Unfortunately, there was not a right-click ->add->New Azure WebJob project in my visual studio, which automatically adds the project to the solution and nessary bindings in my visual studio. I choose to make the WebJob from a .Net 5.0 Console application and add the necessary stuff to that.
If this is a problem with my Visual Studio Community installation or if this is not available in all Visual Studio installations, I don’t know. If you know please comment. I also want the webjob to be deployed and installed alongside the Web App through Azure DevOps, the next blog will be about how to do this. The Webjob will in this case also be timer triggered because it is a synchronisation job that needs to be run continuously. As a side comment, .NET 5 is the successor to .NET Core 3.1 .NET, the word “core” has been removed in the series.
So this is what you should do, to do the same:
Create an Azure .NET 5 WebJob
Prerequisites: You need an Azure Storage account and the connection string from this. To get this u need to do like described in the following article: Create a storage account.
Add a new project to your solution
Right-click on the solution in Visual Studio and choose Add->New Project
Search for the Console App (.NET Core) template
Write Console app in the add a new project dialog search field
Select the Console App (.NET Core)
Select the Console App (.Net core) template
Choose a project name
I choose the name: CompanyName”.Sync.InvoiceInformation.WebJob to follow the standard “Company Name”.”Type”.”Name”.”Functionality”, in this way the name describes precisely what the application does and for who.
Add usings to the program.cs file
Add the below usings to the program:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.WebJobs;
Replace code:
Replace your program.cs main code with this:
public class Program
{
private static IConfiguration Configuration { get; set; }
static async Task Main(string[] args)
{
var builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddAzureStorage();
b.AddTimers();
});
builder.ConfigureServices((context, s) => { ConfigureServices(s); s.BuildServiceProvider(); });
builder.ConfigureLogging(logging =>
{
string appInsightsKey = Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"];
if (!string.IsNullOrEmpty(appInsightsKey))
{
// This uses the options callback to explicitly set the instrumentation key.
logging.AddApplicationInsights(appInsightsKey)
.SetMinimumLevel(LogLevel.Information);
logging.AddApplicationInsightsWebJobs(o => { o.InstrumentationKey = appInsightsKey; });
}
});
var tokenSource = new CancellationTokenSource();
CancellationToken ct = tokenSource.Token;
var host = builder.Build();
using (host)
{
await host.RunAsync(ct);
tokenSource.Dispose();
}
}
}
Add nuget packages
Add nuget packages
Select Manage Nuget Packages
Select the below packages one by one:
Microsoft.Azure.WebJobs
Microsoft.Azure.WebJobs.Extensions
Microsoft.Azure.WebJobs.Extensions.Storage
Microsoft.Azure.WebJobs.Logging.ApplicationInsights
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Logging.Configuration
Microsoft.Extensions.Logging.Console
Microsoft.Extensions.Options.ConfigurationExtensions
My project file now looks like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Version>1.0.2</Version>
<Authors>christiandersen.dk</Authors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.29" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="4.0.1" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="4.0.4" />
<PackageReference Include="Microsoft.Azure.WebJobs.Logging.ApplicationInsights" Version="3.0.27" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
</ItemGroup>
</Project>
Storage binding
The webjobs stores the timer execution information in a storage account so you need one to get this rolling. Be careful not to mix up your storage accounts. Do not use the same account for different webjobs.
Add an application.json file to your project, remember to right-click the file and set it to “copy always”.
Add the following in the json file:
{
"AzureWebJobsStorage": "{storage connection string}"
}
The connection string is available in the Azure Management Portal (classic) by clicking on Storage in the left navigation, highlight the storage account you want to use, and then click the Access Keys button.
Timer Triggered
Add a Functions.cs file with the following content:
public class Functions
{
public async Task TimerTriggerOperation([TimerTrigger("0 */5 * * * *", RunOnStartup = true)] TimerInfo timerInfo, ILogger logger, CancellationToken cancellationToken)
{
try
{
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);
}
catch (Exception exception)
{
logger.LogError("Error with sync message{0} stack trace{1} ", exception.Message, exception.StackTrace);
}
}
}
U should now be able to debug your webjob from the ground.
Comments