Azure Functions

Migrating Azure Functions to .NET 8

by

in

With Azure Functions no longer supporting .NET 6 by the end of 2024 it’s time to migrate your existing functions to .NET 8.

The list of tasks we need to complete for the migration are:

  • Update your project file
  • Update your package references
  • Update your function signatures
  • Add Program.cs to your project
  • Update local.settings.json

Full details on how complete the migration can be found at the official Microsoft documentation.

Update your project file

Open your .csproj file to edit the raw XML. The PropertyGroup will need a new TargetFramework, and you may need to update the AzureFunctionsVersion and add OutputType like below.

<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  <OutputType>Exe</OutputType>
</PropertyGroup>

Next, scroll down to the ItemGroup PackageReference list and remove the reference to Micrososft.NET.Sdk.Functions. It’ll need to be replaced with the below new references. You may have other package references in the list depending on your function application, but feel free to leave those references in place.

<ItemGroup>
   <!--<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.3.0" />-->    
   <FrameworkReference Include="Microsoft.AspNetCore.App" />
   <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
   <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.2" />
   <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.1" />
   <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
   <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
 </ItemGroup>

One final addition may not be necessary, but if you do not have an ItemGroup like the below in your project file go ahead and add one.

<ItemGroup>
  <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext"/>
</ItemGroup>

Save your .csproj file, you should be done here.

Update your package references

Because of the changes in your project file you’re going to see some reference errors in your function classes. Open the .cs files containing your functions and remove the below reference.

using Microsoft.Azure.WebJobs;

And add this reference in its place.

using Microsoft.Azure.Functions.Worker;

There may be the need for additional package references based on the triggers and bindings your function app references. Check the official documentation for a complete list.

Update your function signatures

This seems to be where the most drastic changes took place for the migration. Below is an example of what your new function signature should resemble.

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace Company.Function
{
    public class HttpTriggerCSharp
    {
        private readonly ILogger<HttpTriggerCSharp> _logger;

        public HttpTriggerCSharp(ILogger<HttpTriggerCSharp> logger)
        {
            _logger = logger;
        }

        [Function("HttpTriggerCSharp")]
        public IActionResult Run(
            [HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req)
        {
            _logger.LogInformation("C# HTTP trigger function processed a request.");

            return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!");
        }
    }
}

The important differences of note are:

  • The ILogger is no longer passed in as a parameter to the function call. It’s as private variable for the class that’s initialized by a constructor that wasn’t there prior. Instead of using a class variable like this you can still keep it local to the function call by using FunctionContext as a parameter of the function.
  • Many function attributes have been updated, but most notably is the change from FunctionName to Function.

Add a Program.cs file to your project

Add a new Program.cs file to your project and use the below code.

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services => {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .Build();

host.Run();

This example uses ConfigureFunctionsWebApplication to improve performance for HTTP triggers. If you are not using these you should use ConfigureFunctionsWorkerDefaults.

Update local.settings.json

The last step is to let your application know that you want it to run in the isolated process model instead of the in-process model. Update the FUNCTIONS_WORKER_ROUTINE attribute to be dotnet-isolated.

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
    }
}

Publishing

The local updates are done but you’ll need to publish your changes to Azure. Publishing through Visual Studio gives you the option to update your Azure configuration, but you can make these updates manually. Change the FUNCTIONS_WORKER_RUNTIME application setting to dotnet-isolated.