Search code examples
c#.net-coreazureservicebusbrokeredmessageazure-webjobs-triggered

System.Runtime.Serialization.SerializationException while receiving message from Azure Service Bus


I have two separate applications one .Net Core other in .Net Framework. I have created a service bus sender in .Net core console application. It is sending message to service bus using latest Microsoft.Azure.Webjobs and Microsoft.Azure.Webjobs.ServiceBus nuget packages. Here is sample code for sender.

var message = new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(request)));
var client = new TopicClient(connectionString, TopicName);
await client.SendAsync(message);

The other application written in .NET Framework 4.7 is listening to same service bus. It is using nuget packages Microsoft.Azure.Webjobs and Microsoft.Azure.Webjobs.ServiceBus both version 2.3.0 for .Net Framework. Sample code below.

public class ListenJob
{
    public static void Listen([ServiceBusTrigger("%TopicName%", "%SubscriptionName%")] BrokeredMessage message)
    {
        var messageBody = message.GetBody<string>();
    }
}

On sending message from .Net core console application. The other application is able to detect the message but I get following error on line var messageBody = message.GetBody<string>(); in listener.

Exception while executing function: Applications Microsoft.Azure.WebJobs.Host.FunctionInvocationException : Exception while executing function: Applications ---> System.Runtime.Serialization.SerializationException : There was an error deserializing the object of type System.String. The input source is not correctly formatted. ---> System.Xml.XmlException : The input source is not correctly formatted.


Solution

  • In your sending code the message body is sent as a stream (the bytes are sent as-is and are not encoded). The code you're using to receive with an older Azure Service Bus library is expecting to deserialize a string from those bytes. You should use the same method of sending and receiving when it comes to encoding. I.e. you should get a Stream using message.GetBody<Stream> and read the bytes from the stream and deserializing if needed. More information here.

    To be able to retrieve is as a string using message.GetBody<string> as-is, you'd need to change your sender's code to send DataContract binary serialized string. See here on how to.