2014-06-30 77 views
1

我有一個檢索MSMQ消息的WCF Windows服務。 SubmitPurchaseOrderInMessage似乎不會被調用,也不會看到隊列中的任何消息。代碼如下所示。WCF不處理二進制格式的MSMQ消息

WCF類:

public class OrderProcessorService : IOrderProcessor 
{ 
    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)] 
    [ServiceKnownType(typeof(MyOrder))] 
    public void SubmitPurchaseOrderInMessage(MsmqMessage<MyOrder> ordermsg) 
    { 
     MyOrder po = (MyOrder)ordermsg.Body; 
     Console.WriteLine("Processing id:{0}, name:{1} ", po.ID, po.Name); 
    } 

    public static void Main() 
    { 
     //init queue 
     if (!MessageQueue.Exists(Constants.QUEUE_PATH)) MessageQueue.Create(Constants.QUEUE_PATH, true); 

     //init wcf host via code 
     Uri baseUri = new Uri("http://localhost:7878/msmqsvc"); 
     using (ServiceHost host = new ServiceHost(typeof(OrderProcessorService),baseUri)) 
     { 
      //add metadata behavior 
      ServiceMetadataBehavior smb = new ServiceMetadataBehavior(){ HttpGetEnabled=true}; 
      host.Description.Behaviors.Add(smb); 

      //add service endpoint 
      MsmqIntegrationBinding binding = new MsmqIntegrationBinding(MsmqIntegrationSecurityMode.None); 
      binding.SerializationFormat = MsmqMessageSerializationFormat.Binary; 
      host.AddServiceEndpoint(typeof(ClassLib.IOrderProcessor), binding, "msmq.formatname:DIRECT=OS:" + Constants.QUEUE_PATH); 

      host.Open(); 

      // The service can now be accessed. 
      Console.WriteLine("The service is ready."); 
      Console.WriteLine("Press <ENTER> to terminate service."); 
      Console.ReadLine(); 
      host.Close(); 
     } 
    } 
} 

接口合同:

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")] 
[ServiceKnownType(typeof(MyOrder))] 
public interface IOrderProcessor 
{ 
    [OperationContract(IsOneWay = true, Action = "*")] 
    void SubmitPurchaseOrderInMessage(MsmqMessage<MyOrder> msg); 
} 

陣列的參數可以是可由客戶機被傳遞的任何動態序列化類型。我認爲問題在於這個參數。如果我刪除這個參數和可序列化的屬性以及客戶端中的binding.SerializationFormat,那麼eveything可以正常工作。

Serializable類:

[DataContract(Namespace = "http://Microsoft.ServiceModel.Samples")] 
[Serializable] 
public class MyOrder 
{ 
    [DataMember] 
    public string ID; 

    [DataMember] 
    public string Name; 

    [DataMember] 
    public object[] Parameters; 
} 

[Serializable] 
public class Transaction 
{ 
    public int Amount { get; set; } 
} 

客戶:

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      Run(); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.ToString()); 
     } 
    } 

    static void Run() 
    { 
     MsmqIntegrationBinding binding = new MsmqIntegrationBinding(); 
     binding.Security.Mode = MsmqIntegrationSecurityMode.None; 
     binding.Security.Transport.MsmqAuthenticationMode = MsmqAuthenticationMode.None; 
     binding.Security.Transport.MsmqProtectionLevel = System.Net.Security.ProtectionLevel.None; 
     binding.SerializationFormat = MsmqMessageSerializationFormat.Binary; 
     EndpointAddress address = new EndpointAddress("msmq.formatname:DIRECT=OS:" + Constants.QUEUE_PATH); 

     ChannelFactory<ClassLib.IOrderProcessor> channelFactory = new ChannelFactory<ClassLib.IOrderProcessor>(binding, address); 

     try 
     { 
      ClassLib.IOrderProcessor channel = channelFactory.CreateChannel(); 

      MyOrder order = new MyOrder(); 
      order.ID = DateTime.Now.Ticks.ToString(); 
      order.Name = "Order_" + order.ID; 
      order.Parameters = new object[] { new Transaction { Amount = 108 }, new Transaction { Amount = 100 } }; 
      MsmqMessage<MyOrder> ordermsg = new MsmqMessage<MyOrder>(order); 

      using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required)) 
      { 
       channel.SubmitPurchaseOrderInMessage(ordermsg); 
       scope.Complete(); 
      } 

      Console.WriteLine("Order has been submitted:{0}", ordermsg); 
     } 
     catch(Exception ex) 
     { 

     } 
     finally 
     { 
      channelFactory.Close(); 
     } 
    } 
} 
+0

http://msdn.microsoft.com/en-us/library/ms733025(v=vs.110).aspx –

回答

0

這裏有一些事情要檢查:臨時出站隊列客戶端

  1. 檢查沒有消息。如果此隊列中有消息,則表示該消息無法通過網絡傳輸。因爲你的隊列是事務性的,這可能意味着MSDTC configuration(鏈接支持2012)。

  2. 檢查服務端事務性的死信隊列中沒有消息。如果存在,則表示將消息傳遞到服務隊列時出現問題。可能的權限問題。服務帳戶需要接收消息皮克消息上的隊列,客戶帳戶需要發送消息獲取權限獲取有關目標隊列屬性

  3. Enable msmq logging in windows event log。這將在該框中記錄與MSMQ相關的所有活動。在成功傳輸的服務端,您應該在日誌中看到2個事件:通過網絡發送的消息帶ID的消息已放入隊列

+0

我得到的錯誤是「無法找到程序集‘WCFClientApp’」問題是通過將Transaction類移動到定義MyOrder的庫來解決(暫時)。但是這並沒有解決我的問題,因爲參數(上面的字段)中的對象是從客戶端(WCFClientApp程序集)傳遞的。 – arjun

+0

所以你的錯誤與MSMQ完全沒有關係。 –

+0

是的。但是,您能否就上述問題提供一些想法(關於動態類型) – arjun