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
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
When we run the Node code we're getting the following
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:
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
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
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.