2

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 (e.g. Azure >Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the >extension(s) in your startup code (e.g. 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.

10
  • Windows.Azure.Storage is old package. Try using Microsoft.Azure.Storage instead Commented Dec 5, 2019 at 18:41
  • apologies for the confusion. I am using using Microsoft.WindowsAzure.Storage.Table; Commented Dec 5, 2019 at 19:00
  • this is the same and is old, should not work with dotnetcore 3x. You should use "Microsoft.Azure.Storage" package Commented Dec 5, 2019 at 19:00
  • Thiago, thanks again but I'm not using .net core 3.x I only installed it for something else.That component is installed with Microsoft.Azure.Webjobs.Extensions (3.0.10) and is version 9.3.1 as required because of a dependency on that version in those pacakges. . Commented Dec 5, 2019 at 19:06
  • also - I had it working. So something has changed that I'm not aware of. A vanilla function without any table storage functionality added has exactly the same packages and works as expected. Commented Dec 5, 2019 at 19:08

2 Answers 2

1

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://learn.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.

Sign up to request clarification or add additional context in comments.

Comments

0

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://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-table

1 Comment

Thanks for your reply, I read that before I started development on the function. Followed it in order to get things working initially. and reread it and linked documents. They all say the same thing, nuget version conflicts (or missing settings) are the probable cause.. this doesn't appear to be the case here as there are no conflicts and all required setting are present and correct - I had it working, Unit tested etc.I also checked source control, nothing changed in the couple of days I left it to do other things. The only thing that has changed is I installed .netcore 3.x

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.