0

I am trying to use Azure function output bindings to send message to a service bus topic having one subscription

Following piece of code is doing the job but I am not able to set

  • Custom Properties
  • Message Properties ( contentType, messageId etc )
[Function(nameof(Function1))]
[ServiceBusOutput("test-topic", Connection = "CONN")]
public async Task<OutputData> Run(
    [ServiceBusTrigger("test-queue", Connection = "CONN")]
    ServiceBusReceivedMessage message,
    ServiceBusMessageActions messageActions,
    ICollector<BrokeredMessage> collector
    )
{
    
    //Following return 
    //Is there any way to set custom properties of this message?
    //Along with custom property, I would also like to set messageProperty contentType to application/json

    OutputData outputData = new OutputData
    {
        ID = 123,
        Name = "Test"
    };

    // Complete the message
    await messageActions.CompleteMessageAsync(message);

    return outputData;

    /*As per solution mentioned [here](https://stackoverflow.com/questions/50457428/custom-message-properties-on-azure-queue-topic-message-from-azure-function), I tried to set custom properties but collector is always null.*/
   
    BrokeredMessage brokeredMessage = new();
    brokeredMessage.ContentType = "application/json";
    brokeredMessage.Properties.Add("ID", 123);
    brokeredMessage.Properties.Add("Name", "Test");
    //Injecting  ICollector<BrokeredMessage>  notworking as its always null.
    //collector.Add(brokeredMessage);
}

I can see outputData has reached to its destination but content type is text/plain and I can't add any custom properties. Service Bus Explorer Snap

I am using

  • .NET 9 ( Git repo)
  • Azure service bus ( standard )

Any pointers ?

UPDATE 1 As suggested by @Dasari Kamali I tried using ServiceBusMessage but still observing same behavior

 #region ServiceBusMessage not working
 ServiceBusMessage serviceBusMessage = new ServiceBusMessage();
 serviceBusMessage.ContentType = "application/json";
 serviceBusMessage.ApplicationProperties.Add("ID", 123);
 serviceBusMessage.ApplicationProperties.Add("Name", "Test");
 serviceBusMessage.Body = BinaryData.FromString("Test");
 #endregion
 // Complete the message
 await messageActions.CompleteMessageAsync(message);
 return serviceBusMessage;

Service Bus Explorer snap

3
  • Use ServiceBusMessage instead of BrokeredMessage to set custom properties and ContentType in the output binding. Commented Feb 4 at 11:43
  • @DasariKamali please have a look at UPDATE 1. ServiceBusMessage is also not helpful. Am I missing anything else? Commented Feb 4 at 12:00
  • I used a ServiceBusQueue trigger function that manually creates a ServiceBusSender from a ServiceBusClient and explicitly sends the message using SendMessageAsync(). This approach successfully worked for me to set the ContentType as application/json under the Message Properties in the Topic. Commented Feb 6 at 10:11

2 Answers 2

0

I tried your code and got the same issue, so I tried using a ServiceBusQueue trigger function instead.

It manually creates a ServiceBusSender from a ServiceBusClient and explicitly sends the message using SendMessageAsync(). It successfully worked for me to send message to a Service Bus Topic and setting the ContentType as application/json and Custom Properties.

using System.Text;
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace FunctionApp24
{
    public class Function1
    {
        private readonly ILogger<Function1> _logger;
        private readonly ServiceBusClient _serviceBusClient;

        public Function1(ILogger<Function1> logger, ServiceBusClient serviceBusClient)
        {
            _logger = logger;
            _serviceBusClient = serviceBusClient;
        }

        [Function(nameof(Function1))]
        public async Task Run(
            [ServiceBusTrigger("kamqueue", Connection = "CONN")] ServiceBusReceivedMessage receivedMessage,
            ServiceBusMessageActions messageActions)
        {
            _logger.LogInformation("Received Message ID: {id}", receivedMessage.MessageId);
            _logger.LogInformation("Received Content-Type: {contentType}", receivedMessage.ContentType);
            _logger.LogInformation("Received Body: {body}", Encoding.UTF8.GetString(receivedMessage.Body.ToArray()));

            var outputData = new
            {
                ID = 123,
                Name = "Test"
            };

            string jsonString = JsonConvert.SerializeObject(outputData);
            byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonString);

            var serviceBusMessage = new ServiceBusMessage(jsonBytes)
            {
                ContentType = "application/json", 
                MessageId = Guid.NewGuid().ToString(),
                CorrelationId = receivedMessage.CorrelationId ?? Guid.NewGuid().ToString(),
                ReplyTo = receivedMessage.ReplyTo,
                SessionId = receivedMessage.SessionId,
                PartitionKey = receivedMessage.PartitionKey,
                TimeToLive = TimeSpan.FromMinutes(10)
            };
            serviceBusMessage.ApplicationProperties["ID"] = 123;
            serviceBusMessage.ApplicationProperties["Name"] = "Test";

            _logger.LogInformation("Final Sent Message Content-Type: {contentType}", serviceBusMessage.ContentType);
            var sender = _serviceBusClient.CreateSender("kamtopic");
            await sender.SendMessageAsync(serviceBusMessage);
            await messageActions.CompleteMessageAsync(receivedMessage);
        }
    }
}

Output :

enter image description here

Azure Service Bus Topic :

I successfully set the contentType as application/json and Custom Properties under Message Properties in the Topic.

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. I can see you have constructor injected ServiceBusClient . Have you used new ServiceBusClient(connectionString) somewhere to instantiate ServiceBusClient instance? I am trying to avoid using new ServiceBusClient(connectionString)
I will try without ServiceBusClient and let you know.
0

It looks like using built-in output bindings we can not add ApplicationProperties. I end up using IAzureClientFactory<ServiceBusSender> to create instance of service bus topic client. And subsequently used ServiceBusMessage to send message to service bus topic by setting ApplicationProperties

builder.Services.AddAzureClients(builder =>
{
    builder.AddServiceBusClient(conn);
    builder.AddClient<ServiceBusSender, ServiceBusClientOptions>((_, _, sp) =>
    {
        var sbClient = sp.GetRequiredService<ServiceBusClient>();
        var sender = sbClient.CreateSender("test-topic");
        return sender;
    }).WithName("test-topic");
});
 public Function1(ILogger<Function1> logger, IAzureClientFactory<ServiceBusSender> sbSender)
 {    
     _clientFactory = sbSender;
 }

 [Function(nameof(Function1))]
 public async Task Run(
     [ServiceBusTrigger("test-queue", Connection = "CONN")]
     ServiceBusReceivedMessage message,
     ServiceBusMessageActions messageActions
     )
 {     
     OutputData outputData = new OutputData
     {
         ID = 123,
         Name = "Test"
     };
     #region Working - Use IAzureClientFactory to send message
     var topic = _clientFactory.CreateClient("test-topic");
     var serviceBusMessage = new ServiceBusMessage(JsonConvert.SerializeObject(outputData))
     {
         ContentType = "application/json"
     };
     serviceBusMessage.ApplicationProperties.Add("ID", 123);
     await topic.SendMessageAsync(serviceBusMessage);
     #endregion
     // Complete the message
     await messageActions.CompleteMessageAsync(message);
 }

enter image description here Complete code is available here - azure-sb-topic-output-binding

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.