Contratos da WCF - Namespaces e SerializationExceptions
-
19-09-2019 - |
Pergunta
Estou usando um serviço da web de terceiros que oferece as seguintes chamadas e respostas
http://api.athirdparty.com/rest/foo?apikey=1234
<response>
<foo>this is a foo</foo>
</response>
e
http://api.athirdparty.com/rest/bar?apikey=1234
<response>
<bar>this is a bar</bar>
</response>
Este é o contrato e os tipos de apoio que escrevi
[ServiceContract]
[XmlSerializerFormat]
public interface IFooBarService
{
[OperationContract]
[WebGet(
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Xml,
UriTemplate = "foo?key={apikey}")]
FooResponse GetFoo(string apikey);
[OperationContract]
[WebGet(
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Xml,
UriTemplate = "bar?key={apikey}")]
BarResponse GetBar(string apikey);
}
[XmlRoot("response")]
public class FooResponse
{
[XmlElement("foo")]
public string Foo { get; set; }
}
[XmlRoot("response")]
public class BarResponse
{
[XmlElement("bar")]
public string Bar { get; set; }
}
E então meu cliente se parece com isso
static void Main(string[] args)
{
using (WebChannelFactory<IFooBarService> cf = new WebChannelFactory<IFooBarService>("thirdparty"))
{
var channel = cf.CreateChannel();
FooResponse result = channel.GetFoo("1234");
}
}
Quando eu corro isso, recebo a seguinte exceção
Incapaz de desserializar o corpo XML com o nome da raiz 'Resposta' e o namespace root '' (para a operação 'getFoo' e contrato ('ifoobarService', 'http://tempuri.org/')) Usando XMLSerializer. Verifique se o tipo correspondente ao XML é adicionado à coleção de tipos conhecidos do serviço.
Se eu comentar o GetBar
operação de IFooBarService
, Funciona bem. Sei que estou perdendo um conceito importante aqui - apenas não sei bem o que procurar. Qual é a maneira correta de construir meus tipos de contrato, para que eles possam ser adequadamente desserializados?
Solução
Eu diria que seu serviço de terceiros está gravemente quebrado. Há uma colisão de espaço para nome aqui - há dois elementos nomeados response
Mas com diferentes tipos de esquema XML.
Eu acho que você terá que não usar nenhuma tecnologia .NET que envolve a desaperando este XML. Não haveria maneira de contar .NET no que o tipo .NET Deserrializou o XML.
Você só terá que fazer isso à mão. Linq para XML é útil para esse fim.
Outras dicas
Você pode tentar com a classe de resposta como esta:
[XmlRoot("response")]
public class Response
{
[XmlElement("foo")]
public string Foo { get; set; }
[XmlElement("bar")]
public string Bar { get; set; }
}