Reputation: 326
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.
Upvotes: 5
Views: 10256
Reputation: 326
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;
}
}
Upvotes: 2
Reputation: 51
Use the ServiceBusReceivedMessage clas instead of the string message. It has an ApplicationProperties to read the message properties
Upvotes: 4
Reputation: 25994
Yes, you can. The details of how to depend on the binding library you're using and the SDK it depends on. Microsoft documentation is not bad to start with. Message properties and user properties are available both. See https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus-trigger for more details.
Note that with the latest Service Bus SDK Azure.Messaging.ServiceBus and the new Functions Isolated Worker SDK access to the properties is somewhat different and requires deserialization of JSON values provided via function execution context.
Upvotes: 0