2013-07-16 28 views
5

我們有大約在Azure服務總線客戶端下面的包裝:由編碼BrokeredMessage機構

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

    _queueClient.Send(brokeredMessage); 
} 

隨着SerializeMessageBody

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

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

    return brokeredMessage; 
} 

我寫一個集成測試通過運行SendMessage來檢查此作品,然後使用Service Bus Explorer 2.0查看郵件內容。我們正在這樣做,以確保我們可以使用該工具修復和重新發送消息來修改XML。我發送的消息如下所示:

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

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

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

問題是;當郵件正文的工具看,而不是看起來像XML它,而不是出來象下面這樣:

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

我想這是一個編碼問題;但是我不能在將構造體傳遞給BrokeredMessage構造函數時看到設置編碼的方法;或通過DataContract屬性定義它。

我該如何解決這個編碼問題?我需要提供我自己的serializer/stream還是有辦法強制默認序列化器正確編碼?

回答

7

請嘗試以下代碼。我測試了它,我可以使用我的工具(Service Bus Explorer:http://code.msdn.microsoft.com/windowsazure/Service-Bus-Explorer-f2abca5a#content)以XML格式查看有效負載。 基本上,您需要在BrokeredMessage對象的構造函數中明確指定DataContractSerializer。希望這可以幫助。 僑 保羅

#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

這完美地工作;在構造函數中添加'DataContractSerializer'實例解決了編碼問題,謝謝Paolo。 (PS:[Azure服務總線瀏覽器](http://blogs.msdn.com/b/paolos/archive/2013/04/12/service-bus-explorer-2-0-released.aspx)非常好) –

+3

另外,我在我的博客上發佈了一篇文章,詳細介紹了在使用不同協議/平臺發送和接收消息時,可以對消息正文進行編碼/解碼的不同方式:http://abhishekrlal.com/2012/03/30/formatting -the-content-for-service-bus-messages/ –

+0

當消息已經在DeadLetter隊列中時,是否有任何解決方法?正如我可以讓SBE顯示已發送的消息,而不修改發送機制。我們有一個問題,我們無法通過SBE重新提交消息。看起來像SBE不能重新提交使用'new BrokeredMessage(body)'時創建的消息; – Botis