在WCF服务中公开自定义复杂接口类型时出现问题

在WCF服务中公开自定义复杂接口类型时出现问题,wcf,wcf-binding,wcf-client,Wcf,Wcf Binding,Wcf Client,我正在尝试使用WCF从另一个应用程序获取对象。对于内置类,它可以正常工作,但在尝试从WCF操作返回自定义接口类型时遇到了问题 无论我将接口分别包含在两个应用程序中,还是将其指定为共享程序集,我都会得到相同的结果:一个带有消息“从管道读取时出错:无法识别的错误109”的CommunicationException 界面如下所示: [ServiceContract] public interface IBase { int IntTest { [OperationContra

我正在尝试使用WCF从另一个应用程序获取对象。对于内置类,它可以正常工作,但在尝试从WCF操作返回自定义接口类型时遇到了问题

无论我将接口分别包含在两个应用程序中,还是将其指定为共享程序集,我都会得到相同的结果:一个带有消息“从管道读取时出错:无法识别的错误109”的CommunicationException

界面如下所示:

[ServiceContract]
public interface IBase {
    int IntTest {
        [OperationContract]
        get;
    }
    String StringTest {
        [OperationContract]
        get;
    }
    IOther OtherTest {
        [OperationContract]
        get;
    }
}

[ServiceContract]
public interface IOther {
    String StringTest {
        [OperationContract]
        get;
    }
}
public partial class MainWindow : Window {
    private Base fb;
    private ServiceHost host;

    public MainWindow() {
        InitializeComponent();
        fb = new Base();
        host = new ServiceHost(fb, new Uri[] { new Uri("net.pipe://localhost") });
        host.AddServiceEndpoint(typeof(IBase), new NetNamedPipeBinding(),
            "PipeReverse");
        host.Open();
    }

    private void Window_Closing(object sender, CancelEventArgs e) {
        host.Close();
    }
}
public partial class Form1 : Form {

    IBase obj;

    public Form1() {
        InitializeComponent();
        ChannelFactory<IBase> pipeFactory = new ChannelFactory<IBase>(
            new NetNamedPipeBinding(), new EndpointAddress(
            "net.pipe://localhost/PipeReverse"));

        obj = pipeFactory.CreateChannel();
    }


    private void button2_Click(object sender, EventArgs e) {

        Console.WriteLine("Returns: " + obj.StringTest + " " + 
            obj.StringTest.Length);
        Console.WriteLine("Returns: " + obj.IntTest);
        Console.WriteLine(obj.OtherTest);

    }
}
我的服务器如下所示:

[ServiceContract]
public interface IBase {
    int IntTest {
        [OperationContract]
        get;
    }
    String StringTest {
        [OperationContract]
        get;
    }
    IOther OtherTest {
        [OperationContract]
        get;
    }
}

[ServiceContract]
public interface IOther {
    String StringTest {
        [OperationContract]
        get;
    }
}
public partial class MainWindow : Window {
    private Base fb;
    private ServiceHost host;

    public MainWindow() {
        InitializeComponent();
        fb = new Base();
        host = new ServiceHost(fb, new Uri[] { new Uri("net.pipe://localhost") });
        host.AddServiceEndpoint(typeof(IBase), new NetNamedPipeBinding(),
            "PipeReverse");
        host.Open();
    }

    private void Window_Closing(object sender, CancelEventArgs e) {
        host.Close();
    }
}
public partial class Form1 : Form {

    IBase obj;

    public Form1() {
        InitializeComponent();
        ChannelFactory<IBase> pipeFactory = new ChannelFactory<IBase>(
            new NetNamedPipeBinding(), new EndpointAddress(
            "net.pipe://localhost/PipeReverse"));

        obj = pipeFactory.CreateChannel();
    }


    private void button2_Click(object sender, EventArgs e) {

        Console.WriteLine("Returns: " + obj.StringTest + " " + 
            obj.StringTest.Length);
        Console.WriteLine("Returns: " + obj.IntTest);
        Console.WriteLine(obj.OtherTest);

    }
}
下面是我对接口的实现:

[Serializable]
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class Base : MarshalByRefObject, IBase {
    public int IntTest {
        get { return 4; }
    }

    public string StringTest {
        get { return "A string from Base"; }
    }

    public IOther OtherTest {
        get { return new Other(); }
    }
}

[Serializable]
[DataContract]
public class Other : MarshalByRefObject, IOther {
    [DataMember]
    public string StringTest {
        get { return "A string from Other"; }
    }

}
客户端如下所示:

[ServiceContract]
public interface IBase {
    int IntTest {
        [OperationContract]
        get;
    }
    String StringTest {
        [OperationContract]
        get;
    }
    IOther OtherTest {
        [OperationContract]
        get;
    }
}

[ServiceContract]
public interface IOther {
    String StringTest {
        [OperationContract]
        get;
    }
}
public partial class MainWindow : Window {
    private Base fb;
    private ServiceHost host;

    public MainWindow() {
        InitializeComponent();
        fb = new Base();
        host = new ServiceHost(fb, new Uri[] { new Uri("net.pipe://localhost") });
        host.AddServiceEndpoint(typeof(IBase), new NetNamedPipeBinding(),
            "PipeReverse");
        host.Open();
    }

    private void Window_Closing(object sender, CancelEventArgs e) {
        host.Close();
    }
}
public partial class Form1 : Form {

    IBase obj;

    public Form1() {
        InitializeComponent();
        ChannelFactory<IBase> pipeFactory = new ChannelFactory<IBase>(
            new NetNamedPipeBinding(), new EndpointAddress(
            "net.pipe://localhost/PipeReverse"));

        obj = pipeFactory.CreateChannel();
    }


    private void button2_Click(object sender, EventArgs e) {

        Console.WriteLine("Returns: " + obj.StringTest + " " + 
            obj.StringTest.Length);
        Console.WriteLine("Returns: " + obj.IntTest);
        Console.WriteLine(obj.OtherTest);

    }
}
它给了我一个通信异常,消息是“读取管道时出错:无法识别的错误109”。据我所知,这是由于故障状态导致的管道断裂,但我不知道原因,更重要的是,我不知道如何修复它。有什么想法吗


我没有配置文件,因为上面的代码中完成了所有操作,所以我不知道如何打开跟踪,否则我也会包含该文件。

这通常是一个序列化错误。查看[KnownType]属性。测试这一点的最简单方法是直接调用DataContractSerializer。您可以使用它的WriteObject和ReadObject方法来获取真正的序列化错误。您还可以检查流(通常是FileStream)以确保键入的序列化正确。

返回的属性OtherTest必须是具体类型,而不是接口,否则序列化将无法工作。

我在计算机上运行了此代码。虽然IntTest和StringTest方法没有返回错误,但也没有数据。可能出了什么问题,就是这样!谢谢实际上,这意味着我必须将业务对象放在共享程序集中。我希望能够复制界面,但我想那就必须要做了。再次感谢你的帮助。