3 min read

Handling JSON Objects in Legacy Azure Service Bus SDK

Justin Yoo

When you're building a message-driven architecture on Azure, you highly likely to consider Azure Service Bus as a messaging platform. If you use either Azure Functions or Logic Apps, it's really easy for service integration. However, there are always cases that you would need to use the SDK directly. If you're writing codes in .NET, NuGet has two different SDKs:

The first one is based on .NET Standard, which is a cross-platform library. This library has no problem with handling JSON objects as the message format. On the other hand, the second library is the legacy one that requires the full .NET Framework of 4.6.2 or higher. As the latter supports XML document as its default, it's a little bit tricky to handle the JSON message payloads. But as always, there is a way to get through.

Throughout this short post, I'm going to discuss how to handle the JSON objects in the legacy SDK. First of all, let's have a look at both message object structure.

Microsoft.Azure.ServiceBus.Message

The first one – cross-platform library – uses the message class of Microsoft.Azure.ServiceBus.Message, and it accepts byte array (byte[]) for message body. Therefore, serialising and deserialising JSON objects is not a problem. Here is the sample code snippet:

// Sends message
var @object = new MyClass() { Hello = "World" };
var payload = JsonConvert.SerializeObject(@object);
var body = Encoding.UTF8.GetBytes(payload);
var message = new Message(body);
// Receives message
var body = message.Body;
var payload = Encoding.UTF8.GetString(body);
var @object = JsonConvert.DeserializeObject<MyClass>(payload);

Microsoft.ServiceBus.Messaging.BrokeredMessage

The second one, which is the legacy library, is the one we're dealing with, in this post. It uses the Microsoft.ServiceBus.Messaging.BrokeredMessage class and is instantiated with an XML serialiser as default.

// XML Serialiser
var @object = new MyClass() { Hello = "World" };
var serialiser = new DataContractSerializer(typeof(MyClass));
var message = new BrokeredMessage(@object, serialiser);
// JSON Serialiser
var @object = new MyClass() { Hello = "World" };
var serialiser = new DataContractJsonSerializer(typeof(MyClass));
var message = new BrokeredMessage(@object, serialiser);
// Receives message
var payload = message.GetBody<string>(serialiser);
var @object = JsonConvert.DeserializeObject<MyClass>(payload);

Even if you don't specify the XML serialiser, the message object internally uses it. Therefore, like the second snippet, if you want to use the JSON message, you should use the DataContractJsonSerializer class. Now, here's another question. Should we always use the serialiser for JSON messages? Well, not always. We can do without relying on the serialiser!

// Sends message
var @object = new MyClass() { Hello = "World" };
var payload = JsonConvert.SerializeObject(@object);
var body = Encoding.UTF8.GetBytes(payload);
var stream = new MemoryStream(body);
var message = new BrokeredMessage(stream);
// Receives message
var stream = message.GetBody<Stream>();
var reader = new StreamReader(stream);
var payload = await reader.ReadToEndAsync().ConfigureAwait(false);
var @object = JsonConvert.DeserializeObject<MyClass>(payload);

This code doesn't serialise the object, but serialises it to JSON string and send it to the BrokeredMessage object through the Stream object. Apparently, the BrokeredMessage uses the Stream object inside. Therefore, instead of sending the object directly that requires the serialiser, injecting the stream object directly to the BrokeredMessage instance would be sufficient.

Of course, both approaches have their own use cases, regardless of using the serialiser or not. If your existing application has already been using serialisers, then it would be easy to stay there. Otherwise, the second option may be useful.

What's your thought?