Pergunta

Eu defini a seguinte interface

[ServiceContract]
public interface IHealthProducts
{
    [OperationContract()]
    ResponseClass OrderSelfSignedHealthCertificate();
}

Que retorna o seguinte tipo

[MessageContract]
public class ResponseClass
{
    [MessageBodyMember]
    public string AnimalSpeciesCode
    {
        get;
        set;
    }

    [MessageBodyMember]
    public int VBN
    {
        get;
        set;
    }
}

Eu esperava que o código do cliente gerado exponha o método OrderSelfSignedHealthCertificate da seguinte maneira:

HealthProductsClient client = new HealthProductsClient();
ResponseClass response = client.OrderSelfSignedHealthCertificate();

Em vez disso, as propriedades de ResponseClass não estão embrulhados no responsável, mas expostos assim:

string OrderSelfSignedHealthCertificate(out int VBN)

Quando troco o MessageContract por um atributo DataContract e o MessageBodyMember para um atributo de Datamber, recebo o comportamento esperado (tipo de resposta Responseclass). Eu preciso do MessageContract, no entanto, porque preciso colocar algumas das propriedades no cabeçalho do sabão.

Estou fazendo algo errado? Isso é comportamento normal? Como faço para conseguir um ResponseClass Tipo de retorno, ao usar um MessageContract?

Qualquer ajuda muito apreciada.

Foi útil?

Solução

Quando seu [MessageContract] contém mais de um [MessageBodyMember], então o WCF retornará o primeiro como valor de retorno da chamada de serviço (AnimalSpeciesCode no seu caso), e todos os outros são devolvidos como out ou ref Paraemters.

Você pode resolver isso tendo apenas um único [MessageBodyMember] Em seu contrato de mensagem que encapsula todos os itens que você precisa para retornar, algo assim:

[DataContract]
class CompoundData
{
    public string AnimalSpeciesCode { get; set; }
    public int VBN { get; set; }
}

[MessageContract]
public class ResponseClass
{
    [MessageBodyMember]
    public CompoundData Payload { get; set; }
}

Neste caso, o CompoundData Deve ser o valor de retorno da sua chamada de serviço - contendo os dois elementos que você precisa.

Outras dicas

Obrigado Marc, isso fez isso. Fiz uma classe genérica ResponsWrapper para encapsular os tipos de retorno:

[MessageContract(WrapperNamespace = "http://mynamespace.com")]
public class ResponseWrapper<T>
{
    [MessageBodyMember(Namespace = "http://mynamespace.com")]
    public T Response
    {
        get;
        set;
    }
}

Eu defini o Type de retorno de OrderselfSignedHealthCertificate para ser

ResponseWrapper<ResponseClass> OrderSelfSignedHealthCertificate();

No meu código de cliente, isso se traduz em

ResponseClass OrderSelfSignedHealthCertificate(); 

Que é o que eu queria. Obrigado!

Eu publiquei um acompanhamento para esta pergunta aqui. Os tipos de retorno genéricos não são nomeados corretamente ao usar um MessageContract.

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