Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encoding of BrokeredMessage Body in Azure Service Bus

We have the below wrapper around the Azure Service Bus Client:

public virtual void SendMessage(object bodyObject)
{
    var brokeredMessage = 
        _messageBodySerializer.SerializeMessageBody(bodyObject);

    _queueClient.Send(brokeredMessage);
}

With the SerializeMessageBody consisting of:

public BrokeredMessage SerializeMessageBody(object bodyObject)
{
    var brokeredMessage = new BrokeredMessage(bodyObject);

    brokeredMessage.Properties[MESSAGE_TYPE_PROPERTY_KEY] = 
                    bodyObject.GetType().AssemblyQualifiedName;

    return brokeredMessage;
}

I've written an integration test to check this works by running SendMessage then viewing the message contents using Service Bus Explorer 2.0. We are doing this to ensure we can repair and resend messages using the tool to modify the XML. The message I am sending looks like this:

[DataContract]
public class TestServiceBusMessage
{
    [DataMember]
    public Guid ExternalIdentifier { get; set; }

    [DataMember]
    public int Identifier { get; set; }

    [DataMember]
    public string Name { get; set; }
}

The problem is; when the message body is viewed on the tool, instead of looking like XML it instead comes out like below:

@TestServiceBusMessageWhttp://schemas.datacontract.org/2004/07/IntegrationTests.Common.Azure.ServiceBus   i)http://www.w3.org/2001/XMLSchema-instance@ExternalIdentifier?$13d81b90-d932-437f-a11c-9106412b6c4a@
Identifier?&    @Name?Test Message   

I assume this is an encoding issue; however I cannot see a way to set the encoding when passing the body into the BrokeredMessage constructor; or defining it through a DataContract attribute.

How would I get around this encoding issue? Would I need to provide my own serializer / stream or is there a way to force the default serializer to encode correctly?

like image 772
Luke Merrett Avatar asked Jul 16 '13 09:07

Luke Merrett


1 Answers

try the following code. I tested it and I can see the payload in XML format using my tool (Service Bus Explorer: http://code.msdn.microsoft.com/windowsazure/Service-Bus-Explorer-f2abca5a#content). Basically, you need to explicitly specify the DataContractSerializer in the constructor of the BrokeredMessage object. Hope this helps. Ciao Paolo

#region MyRegion
using System;
using System.Runtime.Serialization;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging; 
#endregion

namespace StackOverflow
{
    static class Program
    {
        #region Private Constants
        private const string QueueName = "stackoverflow";
        private const string MessageType = "MessageType";
        private const string AssemblyName = "AssemblyName";
        private const string ConnectionString = "<your-service-bus-namespace-connectionstring>"; 
        #endregion

        #region Static Methods
        static void Main()
        {
            SendMessage();
        }

        static async void SendMessage()
        {
            try
            {
                // Create NamespaceManager object
                var namespaceManager = NamespaceManager.CreateFromConnectionString(ConnectionString);
                Console.WriteLine("NamespaceManager successfully created.");

                // Create test queue
                if (!namespaceManager.QueueExists(QueueName))
                {
                    namespaceManager.CreateQueue(new QueueDescription(QueueName)
                    {
                        RequiresDuplicateDetection = false,
                        RequiresSession = false,
                        LockDuration = TimeSpan.FromSeconds(60)
                    });
                    Console.WriteLine("Queue successfully created.");
                }

                // Create MessagingFactory object
                var messagingFactory = MessagingFactory.CreateFromConnectionString(ConnectionString);
                Console.WriteLine("MessagingFactory successfully created.");

                // Create MessageSender object
                var messageSender = await messagingFactory.CreateMessageSenderAsync(QueueName);
                Console.WriteLine("MessageSender successfully created.");

                // Create message payload
                var testServiceBusMessage = new TestServiceBusMessage
                {
                    ExternalIdentifier = Guid.NewGuid(),
                    Identifier = 1,
                    Name = "Babo"
                };

                // Create BrokeredMessage object
                using (var brokeredMessage = new BrokeredMessage(testServiceBusMessage,
                                                                 new DataContractSerializer(typeof(TestServiceBusMessage)))
                {
                    Properties = {{MessageType, typeof(TestServiceBusMessage).FullName},
                                  {AssemblyName, typeof(TestServiceBusMessage).AssemblyQualifiedName}}
                })
                {
                    //Send message
                    messageSender.SendAsync(brokeredMessage).Wait();
                }
                Console.WriteLine("Message successfully sent.");
                Console.WriteLine("Press [Enter] to exit");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine("Press [Enter] to exit");
                Console.ReadLine();
            }
        } 
        #endregion
    }

    [DataContract]
    public class TestServiceBusMessage
    {
        [DataMember]
        public Guid ExternalIdentifier { get; set; }

        [DataMember]
        public int Identifier { get; set; }

        [DataMember]
        public string Name { get; set; }
    }
}
like image 98
Paolo Salvatori Avatar answered Nov 11 '22 20:11

Paolo Salvatori