A resposta do WebService é transformada em parâmetro ref ao usar o MessagecOntract
-
24-09-2019 - |
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.
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.