My updated The Things Industries(TTI) connector will use a number of Azure Functions to process Application Integration webhooks (with HTTP Triggers) and Azure Storage Queue messages(with Output Bindings & QueueTriggers).
On a couple of customer projects we had been updating Azure Functions from .NET 4.X to .NET Core 3.1, and most recently .NET Core 5. This process has been surprisingly painful so I decided to build a series of small proof of concept (PoC) projects to explore the problem.
I started with the Visual Studio 2019 Azure Function template and created a plain HTTPTrigger.
public static class Function1
{
[Function("Function1")]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
FunctionContext executionContext)
{
var logger = executionContext.GetLogger("Function1");
logger.LogInformation("C# HTTP trigger function processed a request.");
var response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
response.WriteString("Welcome to Azure Functions!");
return response;
}
}
I changed the AuthorizationLevel to Anonymous to make testing in Azure with Telerik Fiddler easier
public static class Function1
{
[Function("PlainAsync")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData request, FunctionContext executionContext)
{
var logger = executionContext.GetLogger("UplinkMessage");
logger.LogInformation("C# HTTP trigger function processed a request.");
var response = request.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
response.WriteString("Welcome to Azure Functions!");
return new OkResult();
}
}
With not a lot of work I had an Azure Function I could run in the Visual Studio debugger
I could invoke the function using the endpoint displayed as debugging environment started.
I then added more projects to explore asynchronicity, and output bindings
After a bit of “trial and error” I had an HTTPTrigger Function that inserted a message containing the payload of an HTTP POST into an Azure Storage Queue.
[StorageAccount("AzureWebJobsStorage")]
public static class Function1
{
[Function("Uplink")]
public static async Task<HttpTriggerUplinkOutputBindingType> Uplink([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req, FunctionContext context)
{
var logger = context.GetLogger("UplinkMessage");
logger.LogInformation("Uplink processed");
var response = req.CreateResponse(HttpStatusCode.OK);
return new HttpTriggerUplinkOutputBindingType()
{
Name = await req.ReadAsStringAsync(),
HttpReponse = response
};
}
public class HttpTriggerUplinkOutputBindingType
{
[QueueOutput("uplink")]
public string Name { get; set; }
public HttpResponseData HttpReponse { get; set; }
}
}
The key was Multiple Output Bindings so the function could return a result for both the HttpResponseData and Azure Storage Queue operations
After getting the function running locally I deployed it to a Function App running in an App Service plan
Using the Azure Portal I configured an x-functions-key which I could use in Telerik Fiddler

After fixing an accidental truncation of the x-functions-key a message with the body of the POST was created in the Azure Storage Queue.
The aim of this series of PoCs was to have an Azure function that securely (x-functions-key) processed an Hyper Text Transfer Protocol(HTTP) POST with an HTTPTrigger and inserted a message containing the payload into an Azure Storage Queue using an OutputBinding.
Use the contents of this blog post with care as it may not age well.