0

WCF を使用して別のアプリケーションからオブジェクトを取得しようとしています。組み込みのクラスでは正常に動作しますが、WCF 操作からカスタム インターフェイス タイプを返そうとすると問題が発生します。

インターフェイスを両方のアプリケーションに個別に含めるか、共有アセンブリとして指定するかにかかわらず、同じ結果が得られます。

インターフェイスは次のようになります。

[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();
    }
}

そして、これが私のインターフェースの実装です:

[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"; }
    }

}

クライアントは次のようになります。

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);

    }
}

次の行を除いて、すべてが魅力のように機能します。

Console.WriteLine(obj.OtherTest);

「パイプからの読み取り中にエラーが発生しました: 認識できないエラー 109」というメッセージを含む CommunicationException が表示されます。私が知る限り、それは故障状態によるパイプの破損ですが、その理由、またはさらに重要なことに、それを修正する方法がわかりません。何か案は?

上記のコードですべてが行われるため、構成ファイルがないため、トレースをオンにする方法がわかりません。そうしないと、それも含まれていたはずです。

4

2 に答える 2

2

返されるプロパティOtherTestは、インターフェイスではなく具象型である必要があります。そうでない場合、シリアル化は機能しません。

于 2009-04-18T15:43:34.803 に答える
0

これは通常、シリアル化エラーです。[KnownType]属性を確認してください。これをテストする最も簡単な方法は、DataContractSerializerを直接呼び出すことです。WriteObjectメソッドとReadObjectメソッドを使用して、真のシリアル化エラーを取得できます。ストリーム(通常はFileStream)を調べて、タイプが正しくシリアル化されていることを確認することもできます。

于 2009-04-18T12:24:44.670 に答える