Friday, January 9, 2026

Isolated Azure Functions: Multiple Output Bindings with HTTP Functions

In this post, let's look at how we can use multiple output bindings with HTTP-triggered Azure Functions running on the isolated worker model.

When working with HTTP-triggered functions, you often need to return an HTTP response to the caller while also sending data to other services like Azure Service Bus, Azure Queue Storage, etc. This is where multiple output bindings come in handy.

HttpRequestData vs HttpRequest

With Azure Functions isolated worker model, by default we have HttpRequestData and HttpResponseData types from the Microsoft.Azure.Functions.Worker.Extensions.Http package.

However, we can also use ASP.NET Core integration via the Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore NuGet package. This enables using standard ASP.NET Core types including HttpRequestHttpResponse, and IActionResult in HTTP Triggers.

Let's see how multiple output bindings work with both approaches.

To have multiple outputs, we need to create a class that contains our output binding properties.

Using HttpRequestData

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using System.Net;

namespace FunctionApp1;

public class HttpStartWithHttpRequestData
{
    [Function(nameof(HttpStartWithHttpRequestData))]
    public async Task<HttpStartOutputWithHttpResponseDataRun(
        [HttpTrigger(AuthorizationLevel.Function, "get""post")] HttpRequestData req)
    {
        HttpResponseData response = req.CreateResponse(HttpStatusCode.OK);
        await response.WriteStringAsync("Message Sent");

        return new HttpStartOutputWithHttpResponseData()
        {
            ServiceBusMessageContent = "Some Content",
            HttpResponse = response
        };
    }
}

public class HttpStartOutputWithHttpResponseData
{
    [ServiceBusOutput("sbt-test-topic"ServiceBusEntityType.Topic, Connection = "ServiceBusConnection")]
    public string? ServiceBusMessageContent { getset; }

    public HttpResponseData HttpResponse { getset; }
}

With HttpRequestData, the HttpResponseData property doesn't require any special attribute. The function runtime automatically recognizes it as the HTTP response.

Note: The ServiceBusMessageContent property is nullable. If the value isn't set (i.e., it's null), no message will be sent to the Service Bus. This allows you to conditionally send messages based on your business logic.

Using HttpRequest (ASP.NET Core Integration)

When using HttpRequest from the ASP.NET Core integration, things are slightly different. We need to use the [HttpResult] attribute to indicate which property is the HTTP response.

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using System.Net;

namespace FunctionApp1;

public class HttpStartWithHttpRequest
{
    [Function(nameof(HttpStartWithHttpRequest))]
    public HttpStartOutputWithHttpResponse Run(
        [HttpTrigger(AuthorizationLevel.Function, "get""post")] HttpRequest req)
    {
        return new HttpStartOutputWithHttpResponse()
        {
            ServiceBusMessageContent = "Some Content",
            HttpResponse = new ObjectResult("Message Sent")
            {
                StatusCode = (int)HttpStatusCode.OK
            }
        };
    }
}

public class HttpStartOutputWithHttpResponse
{
    [ServiceBusOutput("sbt-test-topic"ServiceBusEntityType.Topic, Connection = "ServiceBusConnection")]
    public string? ServiceBusMessageContent { getset; }

    [HttpResult]
    public IActionResult HttpResponse { getset; }
}

The [HttpResult] attribute is required here because without it, the runtime won't know which property represents the HTTP response.

Note: Similar to the previous example, the ServiceBusMessageContent property is nullable. If the value isn't set, no message will be sent to the Service Bus.

Limitations

There's a significant limitation when it comes to Service Bus output bindings in the isolated worker model. The content type has to be the message body itself - it can be a simple type (like string) or a complex type (a POCO).

You cannot use ServiceBusMessage from the Azure.Messaging.ServiceBus SDK as the output type. If you try to do so, the entire ServiceBusMessage object gets serialized as JSON, resulting in something like this:

{
  "Body""eyJDb250ZW50IjoiU29tZSBDb250ZW50In0=",
  "MessageId"null,
  "PartitionKey"null,
  "SessionId"null,
  "TimeToLive""10675199.02:48:05.4775807",
  "CorrelationId"null,
  "Subject"null,
  "ContentType"null,
  "ApplicationProperties": {}
}

This means you cannot set message properties like CorrelationIdSessionIdSubject, or ApplicationProperties using output bindings in the isolated worker model. If you need to set these properties, you'll have to use the ServiceBusClient directly.

This is a known limitation and has been discussed in several GitHub issues:

Hope this helps.

Happy Coding.

Regards,
Jaliya

No comments:

Post a Comment