2
votes

I am creating a generic WebHook trigger function. A am trying to add output binding to the Azure Queue Storage. From the documentation, I see that CloudQueue type is supported for this output. But when I run the following code in the portal:

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log, CloudQueue outputQueueItem)
{
    log.Info("C# HTTP trigger function processed a request.");
}

it returns me an error:

error CS0246: The type or namespace name 'CloudQueue' could not be found (are you missing a using directive or an assembly reference?)

When I run a new one webhook function that was published from Visual Studio with the following code:

namespace My.Azure.FunctionApp
{
    public static class SurveyWebHook
    {
        [FunctionName("SurveyWebHook")]
        public static async Task<object> Run([HttpTrigger(WebHookType = "genericJson")]HttpRequestMessage req,
           CloudQueue outputQueueItem, TraceWriter log)
        {
            log.Info($"Survey received");

            return req.CreateResponse(HttpStatusCode.OK, new
            {
                message = $"Survey received"
            });
        }
    }
}

it returns me an error:

"'SurveyWebHook' can't be invoked from Azure WebJobs SDK. Is it missing Azure WebJobs SDK attributes?"

How can I actually add CloudQueue type variable as output binding to my WebHook function?

Update: When I use IBinder type:

namespace My.Azure.FunctionApp
{
    public static class SurveyWebHook
    {
        [FunctionName("SurveyWebHook")]
        public static async Task<object> Run([HttpTrigger(WebHookType = "genericJson")]HttpRequestMessage req, IBinder binder, TraceWriter log)
        {
            log.Info($"Survey received");
            string jsonContent = await req.Content.ReadAsStringAsync();
            CloudQueue outputQueue = await binder.BindAsync<CloudQueue>(new QueueAttribute("surveys"));
            await outputQueue.AddMessageAsync(new CloudQueueMessage("Test Message"));

            return req.CreateResponse(HttpStatusCode.OK, new
            {
                message = $"Survey received"
            });
        }
    }
}

It doesn't return an error. But it also doesn't put a message to the queue. The same happens when I use [Queue("myqueue")] CloudQueue. It only works when I use IAsyncCollector<T>

Update: Finally, I have understood why I didn't see messages in my queue. When I publish Azure Functions project from Visual Studio, it adds "configurationSource": "attributes" parameter to the function.json. And this is overrides my connection parameter in the output binding to the default storage account of my Function App service. And my queue was created in this default storage account. I have removed configurationSource parameter and my function started to work as expected.

1
Your binder example works just fine for meMikhail Shilkov

1 Answers

2
votes

To make your first example work, fix the reference - add these lines on top:

#r "Microsoft.WindowsAzure.Storage"

using Microsoft.WindowsAzure.Storage.Queue;

To make your second example work, mark the CloudQueue parameter with QueueAttribute:

[FunctionName("SurveyWebHook")]
public static async Task<object> Run(
    [HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req,
    [Queue("myqueue")] CloudQueue outputQueueItem, 
    TraceWriter log)