contratti WCF - spazi dei nomi e SerializationExceptions
-
19-09-2019 - |
Domanda
Sto utilizzando un servizio web di terze parti che offre i seguenti chiamate e le risposte
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>
Questo è il contratto e il tipo di supporto che ho scritto
[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 poi il mio cliente si presenta così
static void Main(string[] args)
{
using (WebChannelFactory<IFooBarService> cf = new WebChannelFactory<IFooBarService>("thirdparty"))
{
var channel = cf.CreateChannel();
FooResponse result = channel.GetFoo("1234");
}
}
Quando eseguo questo ottengo la seguente eccezione
Impossibile deserializzare corpo XML con il nome root 'risposta' e dello spazio dei nomi root '' (per il funzionamento 'getFoo' e contratto ( 'IFooBarService', ' http://tempuri.org/ ')) utilizzando XmlSerializer. Assicurarsi che si aggiunge al noto tipi di raccolta del servizio del tipo corrispondente al XML.
Se io commento l'operazione GetBar
da IFooBarService
, funziona benissimo. So che mi manca un concetto importante qui - solo che non so bene cosa cercare. Qual è il modo corretto per costruire i miei tipi di contratto, in modo che possano essere adeguatamente deserializzate?
Soluzione
Direi che il vostro servizio di terze parti è mal rotto. C'è una collisione namespace qui -. Ci sono due elementi chiamati response
ma con diversi tipi di schema XML
Penso che si sta andando ad avere per non utilizzare qualsiasi tecnologia .NET che coinvolge deserializzazione XML questo. Non ci sarebbe alcun modo per dire .NET in quale tipo .NET per deserializzare l'XML.
Non vi resta che farlo a mano. LINQ to XML è utile per questo scopo.
Altri suggerimenti
Si può provare con classe di risposta in questo modo:
[XmlRoot("response")]
public class Response
{
[XmlElement("foo")]
public string Foo { get; set; }
[XmlElement("bar")]
public string Bar { get; set; }
}