0
votes

I am trying to output the body of a JSON http POST to Azure Service Bus.

The Azure documentation provides an example but this is a time based function trigger, not an HTTP trigger.

https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus#output

Here is my run.csx

#r "Newtonsoft.Json"


using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;


public static async Task<IActionResult> Run(HttpRequest req)
{

    // req is the object passed into function 

    // read in the whole body, await as it reads to the end to get all?
    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

    // deserialize the request body from JSON to a dynamic object called data
    dynamic data = JsonConvert.DeserializeObject(requestBody);

    // ok so now we have our request body in JSON in the data variable.

    // we need to put it on the service bus somehow
    string message = $"Service Bus queue message created at: {DateTime.Now}";
    outputSbQueue = message;

    return (ActionResult)new OkObjectResult("Ok");

}

And my function.json file:

{
  "bindings": [
    {
      "authLevel": "function",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "serviceBus",
      "connection": "message-bus_CONNECT",
      "name": "outputSbQueue",
      "queueName": "test",
      "direction": "out"
    }
  ]
}

Any guidance is appreciated. I am a newb. This is purely for testing.

UPDATE 5/28/19

This is working:

#r "Newtonsoft.Json"


using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.Net.Http;

public static void Run(HttpRequest req, out string outputSbQueue) 
{

    // Working as of 5.28.2019 10:48 PM


    StreamReader reader = new StreamReader( req.Body );
    string text = reader.ReadToEnd();

    outputSbQueue = text;


}

However I have no logic to return a status to the caller.

2
For output binding or integration related questions, you can refer the examples from Azure Functions Integrate tab while adding\ managing the bindings. Functions App has inbuilt documentation. - Ashokan Sivapragasam

2 Answers

2
votes

Based on your config you should change the function declaration like this:

public static async Task<IActionResult> Run(HttpRequest req, out string outputSbQueue)
{ ... }

The bindings config should be like this:

{
   "bindings": [
   {
     "authLevel": "function",
     "name": "req",
     "type": "httpTrigger",
     "direction": "in",
     "methods": [
       "get",
       "post"
     ]
   },    
   {
     "type": "serviceBus",
     "connection": "message-bus_CONNECT",
     "name": "outputSbQueue",
     "queueName": "test",
     "direction": "out"
   }
 ]
}

Other than that, everything looks ok.

2
votes

You mentioned you need a http trigger. An azurefunction must always have its Bindings

Change the first line of your code like this

public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post")]HttpRequestMessage req, ILogger log,out string outputSbQueue)
{
    //Your code
}

The rest of your code looks fine though. It is always a best pratise to surround your code with a piece of try{} catch block and catch any exceptions and use log.LogError() to throw the message to the logs . This will help you in debugging the function app easily.