2011-09-11 20 views
0

我已經實現了我的第一個WCF應用程序。 我需要一個方法IConsoleData GetData(); 我收到CommunicationException "There was an error reading from the pipe: The channel was closed. (109, 0x6d)."客戶端。我的第一個WCF服務器 - 適用於「字符串」但不適用於自定義界面?

當我更換IConsoleData GetData();string GetData();申請成爲有功能。

我應該如何修復代碼使用IConsoleData GetData()

服務器:

//public interface IConsoleData 
//{ 
// double GetCurrentIndicator(); 
//} 

//public class IConsoleDataImpl : IConsoleData 
//{ 
// public double GetCurrentIndicator() 
// { 
//  return 22; 
// } 
//} 

[ServiceContract] 
public interface IMBClientConsole 
{ 
    [OperationContract] 
    //IConsoleData GetData(); 
    string GetData(); 
} 

public class MBClientConsole : IMBClientConsole 
{ 
    //public IConsoleData GetData() 
    //{ 
    // return new IConsoleDataImpl(); 
    //} 
    public string GetData() 
    { 
     //return new IConsoleDataImpl(); 
     return "hello"; 
    } 
} 

class Log 
{ 

    private ServiceHost _host; 

    public void initialize() 
    { 
     _host = new ServiceHost(typeof (MBClientConsole), 
           new Uri[] 
            { 
             new Uri("net.pipe://localhost") 
            }); 
      _host.AddServiceEndpoint(typeof(IMBClientConsole), 
       new NetNamedPipeBinding(), 
       "PipeReverse"); 

      _host.Open(); 
      System.Threading.Thread.Sleep(1000000); 
      // TODO: host.Close(); 
    } 
} 

客戶:

//public interface IConsoleData 
//{ 
// double GetCurrentIndicator(); 
//} 

[ServiceContract] 
public interface IMBClientConsole 
{ 
    [OperationContract] 
    //IConsoleData GetData(); 
    string GetData(); 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     ChannelFactory<IMBClientConsole> pipeFactory = 
      new ChannelFactory<IMBClientConsole>(
       new NetNamedPipeBinding(), 
       new EndpointAddress(
        "net.pipe://localhost/PipeReverse")); 

     IMBClientConsole pipeProxy = 
      pipeFactory.CreateChannel(); 

     while (true) 
     { 
      string str = Console.ReadLine(); 
      Console.WriteLine("pipe: " + 
       //pipeProxy.GetData().GetCurrentIndicator()); 
       pipeProxy.GetData()); 
     } 
    } 
} 
+0

您報告的錯誤似乎與渠道可用性有關,而非DataContract問題。如果讓GetData返回一個tyoe對象,它將如何工作:IConsoleDataImpl Ah,P.S.刪除第一個我只是叫它ConsoleData如果是一個類;-) –

+0

對於混亂對不起,實際上我很少使用'我'因爲我在Java上編程主要是'我'不是很受歡迎 – javapowered

回答

2

如果您使用的接口,你必須做兩件事情:

  1. 的實現需要可序列化(使用DataContract - 屬性)
  2. 你必須告訴服務known types如果您使用的接口(這裏是IConsoleDataImpl)

讓您的生活更輕鬆,裝飾用DataContract的執行和它的DataMember屬性和使用的實施,而不是接口的成員。

你可以找到很多關於這個here

(不要用「我」開頭的實現名稱)

這裏是沒有已知類型的東西返工,我認爲這將有助於你爲你的 的第一步 - 沒有必要深入挖掘(接口+ KnownTypes)呢。

[DataContract] 
public class ConsoleData 
{ 
    [DataMember] 
    public double CurrentIndicator 
    { 
     get { return 22; } 
     set { /* whatever */ } 
    } 
} 

[ServiceContract] 
public interface IMBClientConsole 
{ 
    [OperationContract] 
    ConsoleData GetData(); 
} 
+0

現在我收到「無法解析符號'DataContract'「。我試圖谷歌的解決方案,但如果你知道它,將不勝感激。 – javapowered

+0

好的,我已將System.Runtime.Serializations引用到引用。現在我收到「屬性'DataMember'在這個聲明類型上是無效的,它只對'property,indexer,field'聲明有效。」 – javapowered

+0

對不起 - 我的錯 – Carsten

1

這裏有幾個問題。首先,你的界面應該被標記爲[DataContract]

[DataContract] 
public interface IConsoleData 
{ 
    double GetCurrentIndicator(); 
} 

現在,當WCF通過電線發送IConsoleData,它要序列化數據的類,把它和反序列化在客戶端上。你的實現的問題是它沒有任何可以序列化的東西。

public class IConsoleDataImpl : IConsoleData 
{ 
    public double GetCurrentIndicator() 
    { 
     return 22; 
    } 
} 

如果你要建立使用svcutil.exe從上面的客戶端,它會創建IConsoleDataImpl類,但GetCurrentIndicator方法不會做任何事情。這裏重要的區別:WCF將傳輸數據,而不是實現。

什麼你可能想在這裏是更多的東西一樣:

[DataContract] 
public interface IConsoleData 
{ 
    [DataMember] 
    double CurrentIndicator { get; set; } 
} 

public class ConsoleDataImpl : IConsoleData 
{ 
    public double CurrentIndicator { get; set; } 
} 


[ServiceContract] 
[KnownType(typeof(ConsoleDataImpl))] 
public interface IMBClientConsole 
{ 
    [OperationContract] 
    IConsoleData GetData(); 
} 

public class MBClientConsole : IMBClientConsole 
{ 
    public IConsoleData GetData() 
    { 
     return new IConsoleDataImpl() { CurrentIndicator = 22 }; 
    } 
} 

雖然在這一點上是不是真的需要IConsoleData界面,我就只是將其刪除。

但基本上要記住的是一般情況下,您希望您的WCF服務包含方法,並且您的數據協定包含屬性(或字段)。如果您從WSDL生成客戶端,那麼DataContract中方法內的實現將不在客戶端中,這隻有在您將帶有DataContracts的共享dll複製到客戶端時纔有效。

希望是有道理的......

+0

感謝,複雜的事情:)我實現如評論所說以上。現在我避免了接口和DataContract關鍵字。迄今爲止的作品.. – javapowered

相關問題