Pergunta

Eu estou tentando se apossar de um objeto de outro aplicativo usando WCF. Com construído em classes que ele funciona bem, mas eu me deparo com probems ao tentar retornar um tipo de interface personalizada da operação WCF.

Se eu incluir a interface em ambas as aplicações em separado, ou espe-lo como um compartilhada montagem, eu obter o mesmo resultado: a CommunicationException com a mensagem "Houve um erro ao ler a partir do tubo: Erro não reconhecido 109".

A aparência da interface como este:

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

[ServiceContract]
public interface IOther {
    String StringTest {
        [OperationContract]
        get;
    }
}

O meu servidor esta aparência:

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

E aqui está a minha implementação da interface:

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

}

A aparência do cliente como este:

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

    }
}

Tudo funciona como um encanto, exceto esta linha:

Console.WriteLine(obj.OtherTest);

Ele me dar uma CommunicationException com a mensagem "Houve um erro ao ler a partir do tubo: Erro não reconhecido 109". Tanto quanto eu posso dizer que é um cano quebrado devido a um estado de falha, mas eu não consigo descobrir por que, ou mais importante como corrigi-lo. Alguma idéia?

Eu não tenho nenhum arquivo de configuração como Ouvia é feito no código acima, então eu não sei como ativar o rastreamento, caso contrário eu teria incluído isso também.

Foi útil?

Solução

A propriedade retornou OtherTest precisa ser um tipo concreto e não uma interface, caso contrário, a serialização não vai funcionar.

Outras dicas

Este é normalmente um erro de serialização. Olhar para o atributo [KnownType]. A maneira mais fácil de testar isso é para invocar o DataContractSerializer diretamente. Você pode usar seus métodos writeObject e ReadObject para obter os verdadeiros erros de serialização. Você também pode inspecionar o fluxo (FileStream geralmente) para se certificar de que você digita Serializa corretamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top