简体   繁体   中英

Azure Functions - table storage binding not working

I have what seems to be a common problem with binding table storage in an azure function. I've read many if not all the answers on stack overflow such as

Why is Azure Function v2 unable to bind to CloudTable?

and as much as I can find on github and in ms documents. Despite trying all fixes, none have worked.

It is all the more confusing because I had it working.. when I returned to the project a couple of days later I started getting this error -

Microsoft.Azure.WebJobs.Host: Error indexing method 'GetCompetitions'. >Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'competitionsTable' to type CloudTable. Make >sure the parameter Type is supported by the binding. If you're using binding extensions (eg Azure >Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the >extension(s) in your startup code (eg builder.AddAzureStorage(), builder.AddServiceBus(), >builder.AddTimers(), etc.).

To get the function working locally I had to follow several steps once I created the function in Visual Studio, as follows:

install relevant nuget packages and add extensionBundle properties to host.json. Host file modified to:

{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[1.*, 2.0.0)"
  }  
}

local.setting.json

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

Funtion:

 [FunctionName("GetCompetitions")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
        [Table("DailyFF", Connection = "AzureWebJobsStorage")] CloudTable competitionsTable,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

                    TableQuery<ActiveCompetition> projectionQuery = new TableQuery<ActiveCompetition>().Select(
            new string[] { "RowKey", "Name" });

        var activeCompetitions = await competitionsTable.ExecuteQuerySegmentedAsync(projectionQuery, null);
        List<Competition> competitions = new List<Competition>();  
        foreach(var c in activeCompetitions.Results)
        {
            competitions.Add(new Competition
            {
                Id = c.RowKey,
                Name = c.Name
            });

        }

        return competitions != null
            ? (ActionResult)new OkObjectResult(competitions)
            : new BadRequestObjectResult("Nothing doing, try something else.");
    }

This worked. I successfully queried local table storage several times.

As I say when I returned to work on it it no longer worked with the error mentioned thrown.

A few things to note: The function does not use any 3rd party libraries so there should be no conflicts. All libraries use Windows.Azure.Storage 9.3.1 (as generated by visual studio) I tried targeting.Net standard as suggested in many articles but it made no difference.

It's possible that I installed the asp.net core 3.x framework between writing the function initially and returning but all settings appear to be correct.

I'm stuck, any help/suggestions appreciated, thanks!

[edit] Something I should add because it's looking like this is the at the root issue.. when I returned to the working function to continue development a new version of the Azure function CLI was installed automatically when I ran the project. I was a little surprised and I had to add a firewall exception as I had done previously. I don't know which version was installed. I've tried setting up a new profile and pointing to the latest version of the CLI downloaded from github (that has brought its own issues as I have to manually delete existing profiles from properties\\launchSettings.json to get it to work). It doesn't fix the function binding issue however.

Seems to me there's a lot of unreliable "fixes" for this scenario so I'd greatly appreciate any links at all to a working demo of azure functions developed in visual studio 2017.

I'm a bit wary of using functions now I have to say. 2 days work and what was working is turning into something of a mare without even touching the working function.

so I figured it out but still not sure why it worked then stopped working without any changes..

I removed changes to host.json as it says extensionBundles aren't required if you install the pacakges with nuget as described here

https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-register#vs

If you use Install-Package to reference a binding, you don't need to use extension bundles. This approach is specific for class libraries built in Visual Studio.

I had read that but as the function worked I hadn't paid much attention to it. Removing

  "extensionBundle": {
  "id": "Microsoft.Azure.Functions.ExtensionBundle",
 "version": "[1.*, 2.0.0)"
}

leaving the host.json file in it's initially generated state fixed the problem.

Just found this:

IQueryable isn't supported in the Functions v2 runtime. An alternative is to use a CloudTable method parameter to read the table by using the Azure Storage SDK. Here's an example of a 2.x function that queries an Azure Functions log table:

If you try to bind to CloudTable and get an error message, make sure that you have a reference to the correct Storage SDK version.

https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-table

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM