I've seen some older posts on this topic, but nothing up-to-date and related to the newer Service Bus and Azure Functions stacks, so thought I'd ask the question again.
On an Azure Function using a Service Bus Trigger, is there a way to access the Service Bus message properties? As far as I can see, it seems that only the message body string is passed into the Run method.
Similarly, on an Azure Function using a Service Bus output binding, is there a way to add message properties to the outbound Service Bus message? Again, as far as I can see, it seems the output binding will only accept a message body string.
Here's example code for an Azure Function that contains a Service Bus trigger to intercept incoming messages AND a Service Bus output binding to send a reply message. In both cases, a Service Bus Message
object -- containing message properties -- is used as the message payload.
Note that this example uses the (slightly older) Microsoft.Azure.ServiceBus
library, and NOT the (newest and latest) Azure.Messaging.ServiceBus
library. As @Sean-Feldman noted in his reply, properties are handled differently in this newest library.
public static class StackOverflowExample
{
// Azure Service Bus constants
private const string ServiceBusTopic = "ServiceBusRequest"; // Use your own topic name
private const string ServiceBusReplyTopic = "ServiceBusReply"; // Use your own reply topic name
private const string ServiceBusSubscription = "AzureFunctionSubscription"; // Use your own subscription name
private const string ServiceBusConnectionString = "ServiceBusConnectionString"; // As you've defined it in local.settings.json
[FunctionName("AzureFunctionServiceBus")] // Use your own Azure Function name
public static void Run(
[ServiceBusTrigger(topicName: ServiceBusTopic, subscriptionName: ServiceBusSubscription, Connection = ServiceBusConnectionString)] Message inputMessage,
ILogger log, // Service Bus trigger
[ServiceBus(ServiceBusReplyTopic, EntityType = EntityType.Topic, Connection = ServiceBusConnectionString)] out Message outputMessage) // Service Bus output binding
{
// Get the message body from the incoming message object.
string inputMessageBody = Encoding.UTF8.GetString(inputMessage.Body);
// Get the message properties from the incoming message object.
// (You can use message properties however you want. In this example,
// we'll just feed them back into the output message.)
IDictionary<string, object> messageProperties = inputMessage.UserProperties;
// Deserialize the incoming message body.
// (Assumes your own class object is serialized as the incoming message payload.)
InputClass inputMessageObject = JsonConvert.DeserializeObject<InputClass>(inputMessageBody);
// Do some work here...
// Create an output message object.
// (Assumes your own class object is the basis of the output message payload.)
OutputClass replyMessageObject = new OutputClass(
requestMessage: inputMessageObject, requestReceivedDateTimeUtc: DateTime.UtcNow,
serviceBusReplyTopic: ServiceBusReplyTopic, status: "Success",statusMessage: tring.Empty);
// Serialize the output message object
string replyMessageBody = JsonConvert.SerializeObject(replyMessageObject);
// Build a Message object for the output message.
// (The outputMessage variable is defined as an "out" parameter above in the Service Bus output binding.
// The Service Bus output binding picks up the outputMessage when the Azure Function completes.)
outputMessage = BuildMessageObject(replyMessageBody, messageProperties);
}
// Static method to build and return a Service Bus Message object given a message string
// and a dictionary of message properties.
private static Message BuildMessageObject(string message, IDictionary<string, object> messageProperties = null)
{
// Create the Service Bus message object
Message messageObject = new Message(Encoding.UTF8.GetBytes(message));
// Add message properties, if defined
if (messageProperties != null)
{
foreach (var messageProperty in messageProperties)
{
messageObject.UserProperties.Add(messageProperty);
}
}
// Return the message object
return messageObject;
}
}