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.