2013-07-16 35 views
5

Chúng tôi có wrapper dưới khoảng Client Azure Service Bus:Encoding của BrokeredMessage Body trong xe buýt Dịch vụ Azure

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

    _queueClient.Send(brokeredMessage); 
} 

Với SerializeMessageBody bao gồm:

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

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

    return brokeredMessage; 
} 

Tôi đã viết một bài kiểm tra tích hợp để kiểm tra tác phẩm này bằng cách chạy SendMessage, sau đó xem nội dung thư bằng cách sử dụng Service Bus Explorer 2.0. Chúng tôi đang làm điều này để đảm bảo chúng tôi có thể sửa chữa và gửi lại tin nhắn bằng cách sử dụng công cụ để sửa đổi XML. Thư tôi gửi trông giống như sau:

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

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

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

Vấn đề là; khi nội dung thư được xem trên công cụ, thay vì trông giống như XML, thay vào đó trông giống như XML, thay vào đó trông giống như dưới đây:

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

Tôi cho rằng đây là sự cố mã hóa; tuy nhiên tôi không thể nhìn thấy một cách để thiết lập mã hóa khi truyền cơ thể vào trong constructor BrokeredMessage; hoặc xác định nó thông qua thuộc tính DataContract.

Tôi sẽ gặp phải vấn đề mã hóa này như thế nào? Tôi có cần cung cấp serializer/stream của riêng mình hoặc có cách nào để buộc trình nối tiếp mặc định mã hóa chính xác không?

Trả lời

7

hãy thử mã sau. Tôi đã thử nghiệm nó và tôi có thể thấy tải trọng ở định dạng XML bằng cách sử dụng công cụ của tôi (Service Bus Explorer: http://code.msdn.microsoft.com/windowsazure/Service-Bus-Explorer-f2abca5a#content). Về cơ bản, bạn cần xác định rõ ràng DataContractSerializer trong hàm tạo của đối tượng BrokeredMessage. Hi vọng điêu nay co ich. 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

Điều đó làm việc hoàn hảo; việc thêm cá thể 'DataContractSerializer' vào hàm tạo giải quyết vấn đề mã hóa, cảm ơn Paolo. (PS: [Azure Service Bus Explorer] (http://blogs.msdn.com/b/paolos/archive/2013/04/12/service-bus-explorer-2-0-released.aspx) là tuyệt vời) –

+3

Ngoài ra, tôi đã xuất bản một bài đăng trên blog của mình để nêu chi tiết các cách khác nhau mà bạn có thể mã hóa/giải mã nội dung thư khi sử dụng các giao thức/nền tảng khác nhau để gửi và nhận thư: http://abhishekrlal.com/2012/03/30/formatting -the-content-for-service-bus-messages/ –

+0

Có cách giải quyết nào khác khi thông báo đang nằm trong hàng đợi DeadLetter không? Như trong tôi có thể nhận được SBE để hiển thị các tin nhắn đã được gửi, mà không sửa đổi cơ chế gửi. Chúng tôi gặp sự cố là chúng tôi không thể gửi lại tin nhắn qua SBE. Có vẻ như SBE không thể gửi lại các tin nhắn được tạo ra khi chỉ sử dụng 'new BrokeredMessage (body);' – Botis

Các vấn đề liên quan