3
votes

I have the following C# function code:

[FunctionName("UpdateCohortsByTenantFunction")]
[return: Queue("my-queue", Connection = "MyStorage")]
//note - I have tried both method decoration and parameter decoration
public static async Task Run([TimerTrigger("* * * * * *")]TimerInfo myTimer, IAsyncCollector<AudienceMessage> output)
{
    //some logic
    foreach (var audience in audiences)
    {
        await output.AddAsync(new AudienceMessage
        {
            AudienceId = audience.Id,
            TenantId = tenant.Id
        });
    }
}

Which produces the following function.json:

{
   "generatedBy": "Microsoft.NET.Sdk.Functions.Generator-1.0.6",
   "configurationSource": "attributes",
   "bindings": [
   {
       "type": "timerTrigger",
       "schedule": "* * * * * *",
       "useMonitor": true,
       "runOnStartup": false,
       "name": "myTimer"
   }
  ],
  "disabled": false,
  "scriptFile": "../bin/MyApp.App.Tasks.Functions.dll",
  "entryPoint": "MyApp.App.Tasks.Functions.UpdateCohortsByTenantFunction.Run"
}

According to the documentation here the json output should contain an binding to my queue with an "out" direction. Ie:

{
  "type": "queue",
  "direction": "out",
  "name": "$return",
  "queueName": "outqueue",
  "connection": "MyStorageConnectionAppSetting",
}

When I try to run the queue via the npm tools (config described here), I get the following error:

Run: Microsoft.Azure.WebJobs.Host: Error indexing method 'UpdateCohortsByTenantFunction.Run'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'output' to type IAsyncCollector`1. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. config.UseServiceBus(), config.UseTimers(), etc.).

The documentation contains no references to binding via startup code. My understanding is that this is done via the attributes described in the Microsoft documentation linked above, and in my example code, but the error message suggests otherwise.

1

1 Answers

7
votes
  1. You should decorate your parameter with attribute, not return value:

    public static async Task Run(
        [TimerTrigger("* * * * * *")]TimerInfo myTimer,
        [Queue("my-queue", Connection = "MyStg")] IAsyncCollector<AudienceMessage> output)
    
  2. No output binding in function.json is to be expected. Attribute-defined bindings are not transferred to generated function.json. They will still work, don't worry.