All Articles

Send a message to an Azure Service Bus Queue with C# and reading it in Node - Interoperability problems

The other day someone asked me to look at some code in Node. Basically, the code was reading a message from an Azure Service Bus queue.  There was nothing wrong with the code, however the person who asked me to help him told me that the message that he was getting from the queue it wasn't exactly equal to the one that was being sent. The message was being written in C#, using the Azure Service Bus SDK. Looking at the C# code, the message was being written with the following code

image

Nothing special. We are just sending in the message's payload a string representation of the JSON object { 'a': '1'} 

And the Node code is reading the message with the following code

image

When we run the Node code we're getting the following

image

We are getting an exception when we try to parse the body of the message as JSON because the body of the message we are receiving is

"@\u0006string\b3http://schemas.microsoft.com/2003/10/Serialization/?\u000b{ \"a\": \"1\"}"

And not just what we've sent in C# "{ \"a\": \"1\"}". So, what's happening here?

The problem here is that we are using the BrokeredMessage's constructor that accepts an object as its argument

new BrokeredMessage(payload)

Let's look at its documentation 

Initializes a new instance of the BrokeredMessage class from a given object by using DataContractSerializer with a binary XmlDictionaryWriter.

So, the payload is being serialized using DataContractSerializer with a binary XmlDictionaryWriter and this is the cause that explains why the body of the message has in its start the type indication

@\u0006string\b3http://schemas.microsoft.com/2003/10/Serialization/?\u000b

How to fix it?

We have two options to fix the problem: 

  1. when reading the message in Node strip the part that we are not interested in
  2. or guarantee that the body of the message is just what we are sending, nothing more

I will focus on the 2nd fix because in my opinion is cleaner. To guarantee tha the body of the message is just what we are sending we have to use other BrokeredMessage's constructor, passing a Stream as an argument

public BrokeredMessage(Stream messageBodyStream, bool ownsStream)

Here what it's said in documentation

Initializes a new instance of the BrokeredMessage class using the supplied stream as its body.

So, in this case we have full control what will be the body of the message. Let's rewrite our C# code to use this constructor

image

The main difference here is that we are converting our payload string to a stream and use this stream to build our brokered message.

After sending the message to the queue, let's run again the node code

image

Now we are able to parse the body as JSON and everything is working as expected.

Conclusion: we have to be careful when we have two different worlds in the ends (.Net C#  vs Node) and double check for interoperability problems.