2013-07-16 12 views
5

Mamy poniżej otoki wokół Klienta Azure Service Bus:Kodowanie BrokeredMessage Ciała w Azure Service Bus

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

    _queueClient.Send(brokeredMessage); 
} 

Z SerializeMessageBody składający się z:

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

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

    return brokeredMessage; 
} 

Pisałem test integracji aby to sprawdzić, uruchom program SendMessage, a następnie przejrzyj zawartość wiadomości, używając Service Bus Explorer 2.0. Robimy to, aby zapewnić, że możemy naprawić i ponownie wysłać wiadomości za pomocą narzędzia do modyfikacji XML. Wysyłany komunikat wygląda następująco:

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

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

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

Problem polega na tym; gdy treść wiadomości jest wyświetlana w narzędziu, zamiast wyglądać jak XML, wychodzi ona jak poniżej:

@TestServiceBusMessageWhttp://schemas.datacontract.org/2004/07/IntegrationTests.Common.Azure.ServiceBus i)http://www.w3.org/2001/[email protected][email protected] 
Identifier?& @Name?Test Message 

Zakładam, że jest to problem związany z kodowaniem; jednak nie widzę sposobu, aby ustawić kodowanie podczas przekazywania ciała do konstruktora BrokeredMessage; lub definiowanie go za pomocą atrybutu DataContract.

Jak obejść ten problem z kodowaniem? Czy muszę podać własny kod? Czy istnieje sposób zmuszenia domyślnego serializera do prawidłowego kodowania?

Odpowiedz

7

wypróbuj poniższy kod. Przetestowałem to i widzę ładunek w formacie XML za pomocą mojego narzędzia (Service Bus Explorer: http://code.msdn.microsoft.com/windowsazure/Service-Bus-Explorer-f2abca5a#content). Zasadniczo należy jawnie określić DataContractSerializer w konstruktorze obiektu BrokeredMessage. Mam nadzieję że to pomoże. 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; } 
    } 
} 
+0

To działało idealnie; dodanie instancji 'DataContractSerializer' w konstruktorze rozwiązuje problem z kodowaniem, dziękuję Paolo. (PS: [Azure Service Bus Explorer] (http://blogs.msdn.com/b/paolos/archive/2013/04/12/service-bus-explorer-2-0-released.aspx) jest doskonały) –

+3

Opublikowałem także post na moim blogu, który opisuje różne sposoby kodowania/dekodowania treści wiadomości przy użyciu różnych protokołów/platform do wysyłania i odbierania wiadomości: http://abhishekrlal.com/2012/03/30/formatting -the-content-for-service-bus-messages/ –

+0

Czy istnieje sposób obejścia problemu, gdy wiadomość jest już umieszczona w kolejce DeadLetter? Tak jak mogę, SBE pokazuje komunikat, który już został wysłany, bez modyfikowania mechanizmu wysyłania. Mamy problem z tym, że nie możemy ponownie przesłać wiadomości za pośrednictwem SBE. Wygląda na to, że SBE nie może ponownie wysłać wiadomości, które zostały utworzone podczas używania 'nowej BrokeredMessage (body);' – Botis

Powiązane problemy