4

I have trouble with the Microsoft.Azure.ServiceBus.Message class. I want to create a Message object containing a payload object and then read this object back from it. In my current example I am not even sending the Message through a real Azure bus; I'm just creating it in memory and then trying to read it.

I cannot figure out what type I am supposed to read the message body as. I've tried byte[], string and the original object type. In all my cases I get an XmlException: "The input source is not correctly formatted".

Can someone please tell me what I am doing wrong, either when encoding or decoding the Message?

    [DataContract]
    public class Thingy
    {
        [DataMember]
        public string Doodad { get; set; }
    }

    private static Message CreateMessage()
    {
        var entityMessage = new Thingy {Doodad = "foobar"};
        var serializedMessageBody = JsonConvert.SerializeObject(entityMessage);
        var contentType = typeof(Thingy).AssemblyQualifiedName;
        var bytes = Encoding.UTF8.GetBytes(serializedMessageBody);
        var message = new Message(bytes) {ContentType = contentType};
        return message;
    }

    [Test]
    public void ReadMessageBytes()
    {
        var message = CreateMessage();
        var body = message.GetBody<byte[]>();
        Console.WriteLine(body);
    }

    [Test]
    public void ReadMessageString()
    {
        var message = CreateMessage();
        var body = message.GetBody<string>();
        Console.WriteLine(body);
    }

    [Test]
    public void ReadMessageThingy()
    {
        var message = CreateMessage();
        var body = message.GetBody<Thingy>();
        Console.WriteLine(body);
    }
Claus Appel
  • 379
  • 1
  • 4
  • 13

2 Answers2

3

I found out that this works:

    [Test]
    public void ReadMessageProperly()
    {
        var message = CreateMessage();
        var body = message.Body;
        var text = Encoding.UTF8.GetString(body);
        var thingy = JsonConvert.DeserializeObject<Thingy>(text);
        Assert.IsInstanceOf<Thingy>(thingy);
        Assert.AreEqual("foobar", thingy.Doodad);
    }
Claus Appel
  • 379
  • 1
  • 4
  • 13
-1

When creating a BrokeredMessage using custom DataContract type and using DataContractSerializer :

Record recordDataContract = new Record { Id = "DataContract Record" };

BrokeredMessage recordDataContractMessage = new BrokeredMessage(recordDataContract, new DataContractSerializer(typeof(Record)));

You can receive this message as:

Record r = receiveMessage.GetBody<Record>(new DataContractSerializer(typeof(Record)));

When creating a **BrokeredMessage** using custom **DataContract** type and using default serializer (DataContract + Binary Xml):

[DataContract(Namespace = "")]

class Record {

[DataMember]

public string Id { get; set; }

}


Record recordDefault = new Record { Id = "default Record" };

BrokeredMessage recordDefaultMessage = new BrokeredMessage(recordDefault);

You can receive this message as:

Record r = receiveMessage.GetBody<Record>();

For additional reference , you can check this blog. It has detailed example for different scenarios.

Hope it helps.

Mohit Verma
  • 5,140
  • 2
  • 12
  • 27
  • Your answer uses `Microsoft.ServiceBus.Messaging.BrokeredMessage` rather than `Microsoft.Azure.ServiceBus.Message`. As far as I can tell, I need `Message` because I rely on `QueueClient.RegisterMessageHandler`, which uses `Message` rather than `BrokeredMessage`. – Claus Appel Jan 07 '20 at 10:31
  • Your suggestion corresponds to my test method `ReadMessageThingy`, which failed. Moreover, your setup is completely different because `BrokeredMessage` has a different interface than `Message`. – Claus Appel Jan 07 '20 at 10:47