'FunctionsStartup vs IWebJobsStartup, problems reading HttpHeaders on the request

I am building a .NET Core 3.1 Azure Functions application on my local and am trying to configure a startup class. When I implement a class to inherit from FunctionsStartup I cannot import a .net core 3.1 class library into my project. If I do so and try to run the app, I get the following error in the execution window:

Microsoft.Azure.Functions.Extensions: Method not found: Microsoft.Extensions.Configuration.IConfigurationBuilder Microsoft.Azure.WebJobs.Hosting.IWebJobsConfigurationBuilder.get_ConfigurationBuilder()'. Value cannot be null. (Parameter 'provider')

When I switch the Startup base class to IWebJobsStartup the app starts fine. When I make a request and try stepping through the code I run into a problem. I can step through an initial portion of code (so I know my request is successfully received) but I am not able to step into one of my functions. I get a download prompt and a page opens up in the VS work area that has the error message TaskMethodInvker.cs not found with the tag line You need to find TaskMethodInvoker.cs to view the source for the current call stack frame. The below code shows my function:

[FunctionName("HttpAuth")]
public async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
    ExecutionContext context,
    ILogger log)
{
    GetAzureADConfiguration(context);
    var jwt = GetJwtFromHeader(req);
}

private JwtSecurityToken GetSecurityToken(string encodedToken)
{
    ...
}

private string GetJwtFromHeader(HttpRequest req)
{
    var authorizationHeader = req.Headers?["Authorization"];
    string[] parts = authorizationHeader?.ToString().Split(null) ?? new string[0];
    return (parts.Length == 2 && parts[0].Equals("Bearer")) ? parts[1] : string.Empty;
}

The GetAzureADConfiguration function is executing, GetJwtFromHeader is not. It seems that any function trying to access the Header dictionary via code can not be stepped into and causes my error. However, if I inspect the object in the watch window, I see the correct value.

Here is my WebJobStartUp code:

[assembly: WebJobsStartup(typeof(StartUp))]
namespace CriticalPath.Api.Functions
{
    class StartUp : IWebJobsStartup 
    {
        public void Configure(IWebJobsBuilder builder) 
        {
            ...
        }
    }
}

Here is what I tried with FunctionsStartup

[assembly: FunctionsStartup(typeof(Startup))]
namespace CriticalPath.Api.Functions
{
    class StartUp : FunctionsStartup
    {
        public void Configure(IWebJobsBuilder builder)
        {
            ...
        }
    }
}

Why can't I step through my code that references the request's headers? What is the difference between FunctionsStartup and IWebJobsStartup. How do I access the headers if I want to use IWebJobsStartup?



Solution 1:[1]

I was able to fix the problem. Here is the blow-by-blow: my problem revolved around trying to import a class library that used a dependency that conflicted with my Azure Functions app. How I found this: I created a fresh Azure Functions v3 project and .NET Core 3.1 library. After experimenting with it a bit I found that while inheriting from FunctionsStartup (not WebJobStartup) in my Startup class, I was able to successfully import an empty project. In my function, I added code that accessed an entry from the req.Headers dictionary so I can see when running the function failed. Once I got an empty project working, I looked at a project that wasn't importing correctly and one by one added references in the non-working project to my empty project. With each reference I tested my Azure Function to see what breaks it. When I got to Microsoft.Extensions.Configuration v5.0, my function broke. I downgraded this dependency to v3.1.13 and the function worked. So in the project that didn't work I was using Configuration to access variables in my secrets there must have been a mismatch in versions. Fixing this worked. I then wanted to create a custom attribute. I switched over to using WebJobStartup and it the web trigger worked.

Solution 2:[2]

I had a similar situation with get_configurationbuilder and after updating to VS2022 and .NET 6. In my case, the system was pointing to a WebJobsBuilderExtensions.cs file in the version 3 AzureFunctionTools Release folder... not the latest v4 folder. I installed the tools again (https://github.com/Azure/azure-functions-core-tools) to make sure I was up to date and then opened the csproj file to change it from v3 to AzureFunctionsVersion v4 and all was well.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 marc_s
Solution 2