2013-07-16 7 views
5

Abbiamo l'involucro sotto intorno al Cliente Azure Service Bus:Codifica di BrokeredMessage Corpo in Azure Service Bus

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

    _queueClient.Send(brokeredMessage); 
} 

Con la SerializeMessageBody composto da:

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

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

    return brokeredMessage; 
} 

Ho scritto un test di integrazione per verificare questo funziona eseguendo SendMessage quindi visualizzando il contenuto del messaggio utilizzando Service Bus Explorer 2.0. Lo stiamo facendo per garantire che possiamo riparare e inviare nuovamente i messaggi utilizzando lo strumento per modificare l'XML. Il messaggio che sto inviando assomiglia a questo:

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

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

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

Il problema è; quando il corpo del messaggio viene visualizzato sullo strumento, invece di guardare come XML invece viene fuori come di seguito:

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

Suppongo che questo è un problema di codifica; tuttavia non riesco a vedere un modo per impostare la codifica quando si passa il corpo nel costruttore BrokeredMessage; o definendolo tramite un attributo DataContract.

Come risolvere questo problema di codifica? Dovrei fornire il mio serializer/stream o c'è un modo per forzare il serializzatore predefinito a codificare correttamente?

risposta

7

provare il seguente codice. L'ho provato e posso vedere il carico utile in formato XML usando il mio strumento (Service Bus Explorer: http://code.msdn.microsoft.com/windowsazure/Service-Bus-Explorer-f2abca5a#content). Fondamentalmente, è necessario specificare esplicitamente DataContractSerializer nel costruttore dell'oggetto BrokeredMessage. Spero che questo ti aiuti. 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

che ha funzionato alla perfezione; l'aggiunta dell'istanza 'DataContractSerializer' nel costruttore risolve il problema di codifica, grazie Paolo. (PS: [Azure Service Bus Explorer] (http://blogs.msdn.com/b/paolos/archive/2013/04/12/service-bus-explorer-2-0-released.aspx) è eccellente) –

+3

Inoltre ho pubblicato un post sul mio blog che descrive in dettaglio i diversi modi in cui è possibile codificare/decodificare il corpo del messaggio quando si utilizzano diversi protocolli/piattaforme per inviare e ricevere messaggi: http://abhishekrlal.com/2012/03/30/formatting -the-content-for-service-bus-messages/ –

+0

Esiste una soluzione alternativa quando il messaggio è già presente nella coda DeadLetter? Come posso ottenere SBE per mostrare il messaggio che è stato già inviato, senza modificare il meccanismo di invio. Abbiamo un problema che non possiamo inviare nuovamente i messaggi tramite SBE. Sembra che SBE non riesca a inviare nuovamente i messaggi che sono stati creati usando semplicemente 'new BrokeredMessage (body);' – Botis