Can ApplicationProperties/CustomProperties be set on the ServiceBusMessage when working with ServiceBusOutput-outputbinding in C#?

167 views Asked by At

I'm using the ServiceBusOutput in my C# function, but I need to set an ApplicationProperty on the message I'm sending, as it's used by the topic-subscription to filter the message to the relevant subscriptions. However, when I use the ServiceBusMessage-object as the return-object and set the ApplicationProperty on it, the entire ServiceBusMessage gets used as the body. This is not the desired result, as I want my original body (passed to the ServiceBusMessage) as messagebody. When I pass the body as return-object, the body of the message is correct, but there is no way for me to set the ApplicationProperties as far as I know (no way to pass them in the ServiceBusOutput-attribute).

Am I missing something, or is it just not possible to add ApplicationProperties when using the outputbinding?

var message = new ServiceBusMessage("body");
message.ApplicationProperties.Add("Type", "Type1");

return message;

EDIT:

Forgot to mention I'm using the isolated worker. I've also added a more complete snippet of my function, as I'm trying to both write something to Cosmos and post a message on ServiceBus.

public class ListenerFunction
{
    private readonly ILogger<ListenerFunction> _logger;
    public ListenerFunction(ILogger<ListenerFunction> logger)
    {
        _logger = Guard.Against.Null(logger, nameof(logger));
    }

    [Function("ListenerFunction")]
    public ListenerFunctionOutput Run([ServiceBusTrigger(
            "%Topic%",
            "%Subscription%",
            Connection = "connection",
            IsSessionsEnabled = false)] ServiceBusMessageWithBlobUrl serviceBusMessageWithBlobUrl,
        [BlobInput("{UploadedBlobUrl}", Connection = "blobConnection")] Entity entity,
        FunctionContext context)
    {
        _logger.LogInformation("C# ServiceBus topic trigger function processed message: {inputMaterialEventServiceBusMessage}", serviceBusMessageWithBlobUrl.ToString());

        var id = Guid.NewGuid();
        var output =  new ListenerFunctionOutput
        {
            CosmosDbDocument = entity with { Id = id},
            ServiceBusNotification = new ServiceBusMessage(JsonConvert.SerializeObject(new EntityNotification(id, serviceBusMessageWithBlobUrl.CorrelationId, entity with { Id = id}), Formatting.Indented))
        };
        output.ServiceBusNotification.ApplicationProperties.Add("Type", "Type1");


        return output;

        
    }

    public class ListenerFunctionOutput
    {
        [CosmosDBOutput(databaseName: "%database%", containerName: "%container%", Connection = "databaseConnection")]
        public Entity CosmosDbDocument { get; set; }

        [ServiceBusOutput("%topic%", EntityType = ServiceBusEntityType.Topic, Connection = "connection")]
        public ServiceBusMessage ServiceBusNotification { get; set; }
    }
}
2

There are 2 answers

1
RithwikBojja On

I have reproduced in my environment and below are my expected results:

Function.cs:

using System;
using System.Text;
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;

namespace FunctionApp82
{
    public class Function1
    {
        [FunctionName("Function1")]
        public static void Run([ServiceBusTrigger("myqueue", Connection = "connec")]string myQueueItem, ILogger log, [ServiceBus("rithwikqueue", Connection = "connec")] out Message message)
        {
            log.LogInformation($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
            message = new Message(Encoding.UTF8.GetBytes(myQueueItem));
            message.UserProperties.Add("sender", "Chotu");


        }
    }
}

Output:

enter image description here

enter image description here

enter image description here

2
ReservoirDevs On

There is no current way of doing this in Isolated with the ServiceBusOutputAttribute.

Instead, send the message via code. I hit this exact same issue, and I've stripped out the output attribute and am using MassTransit instead. Works perfectly for my use case.