2011-05-14 100 views
2

我有一個異步WCF服務器(我派生了我自己的clientbase類),我從我的客戶端應用程序中調用它。嘗試序列化參數時發生錯誤http://tempuri.org/:callback

然而,當這種方法被稱爲:

public IAsyncResult Beginxxx(string path, AsyncCallback callback, object state) 
{ 
    return Channel.Beginxxx(path, callback, state); 
} 

我得到這個異常:

{「,而試圖序列參數http://tempuri.org/:callback有一個錯誤的InnerException消息是 '類型'。 System.DelegateSerializationHolder + DelegateEntry'與數據協定名稱'DelegateSerializationHolder.DelegateEntry:http://schemas.datacontract.org/2004/07/System'不需要添加任何靜態未知的類型到已知類型的列表中 - 例如,通過使用KnownTypeAttribute attri或通過將它們添加到傳遞給DataContractSerializer的已知類型列表中。請參閱的InnerException更多的細節。「}

如果我有我自己的類有自己的屬性,這個例外是有意義,但是這是一個標準的.NET類型(AsyncCallback的,我相信除了抱怨)。什麼我試圖做的沒有這個問題的代碼示例(我改變了對同類型的結合,我使用 - 命名管道)。

什麼是錯的

回答

6

你可能忘了嗎?在[OperationContract]屬性中添加(AsyncPattern = true)屬性,下面的例子顯示了兩個客戶端,一個(錯誤)和你正在看到的確切錯誤,一個(正確)獸人。唯一的區別是操作合同中的AsyncPattern = true。

public class StackOverflow_5999249_751090 
{ 
    [ServiceContract(Name = "ITest", Namespace = "")] 
    public interface ITest 
    { 
     [OperationContract] 
     string Echo(string path); 
    } 

    public class Service : ITest 
    { 
     public string Echo(string path) { return path; } 
    } 

    [ServiceContract(Name = "ITest", Namespace = "")] 
    public interface ITestClient_Wrong 
    { 
     [OperationContract] 
     IAsyncResult BeginEcho(string path, AsyncCallback callback, object state); 
     string EndEcho(IAsyncResult asyncResult); 
    } 

    [ServiceContract(Name = "ITest", Namespace = "")] 
    public interface ITestClient_Correct 
    { 
     [OperationContract(AsyncPattern = true)] 
     IAsyncResult BeginEcho(string path, AsyncCallback callback, object state); 
     string EndEcho(IAsyncResult asyncResult); 
    } 

    static void PrintException(Exception e) 
    { 
     int indent = 2; 
     while (e != null) 
     { 
      for (int i = 0; i < indent; i++) 
      { 
       Console.Write(' '); 
      } 

      Console.WriteLine("{0}: {1}", e.GetType().FullName, e.Message); 
      indent += 2; 
      e = e.InnerException; 
     } 
    } 

    public static void Test() 
    { 
     string baseAddress = "net.pipe://localhost/Service"; 
     ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); 
     host.AddServiceEndpoint(typeof(ITest), new NetNamedPipeBinding(), ""); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     AutoResetEvent evt = new AutoResetEvent(false); 

     Console.WriteLine("Correct"); 
     ChannelFactory<ITestClient_Correct> factory1 = new ChannelFactory<ITestClient_Correct>(new NetNamedPipeBinding(), new EndpointAddress(baseAddress)); 
     ITestClient_Correct proxy1 = factory1.CreateChannel(); 
     proxy1.BeginEcho("Hello", delegate(IAsyncResult ar) 
     { 
      Console.WriteLine("Result from correct: {0}", proxy1.EndEcho(ar)); 
      evt.Set(); 
     }, null); 
     evt.WaitOne(); 

     Console.WriteLine("Wrong"); 
     ChannelFactory<ITestClient_Wrong> factory2 = new ChannelFactory<ITestClient_Wrong>(new NetNamedPipeBinding(), new EndpointAddress(baseAddress)); 
     ITestClient_Wrong proxy2 = factory2.CreateChannel(); 
     try 
     { 
      proxy2.BeginEcho("Hello", delegate(IAsyncResult ar) 
      { 
       try 
       { 
        Console.WriteLine("Result from wrong: {0}", proxy2.EndEcho(ar)); 
       } 
       catch (Exception e) 
       { 
        PrintException(e); 
       } 
       evt.Set(); 
      }, null); 
      evt.WaitOne(); 
     } 
     catch (Exception e2) 
     { 
      PrintException(e2); 
     } 

     Console.WriteLine("Press ENTER to close"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 
+0

我在看到你的帖子之前就意識到了,無論如何,謝謝! – dotnetdev

相關問題