Pregunta

Estoy usando un servicio web de terceros que ofrece las siguientes llamadas y respuestas.

http://api.athirdparty.com/rest/foo?apikey=1234

<response>
  <foo>this is a foo</foo>
</response>

y

http://api.athirdparty.com/rest/bar?apikey=1234

<response>
  <bar>this is a bar</bar>
</response>

Este es el contrato y los tipos de apoyo que escribí

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

Y luego mi cliente se ve así

static void Main(string[] args)
{
    using (WebChannelFactory<IFooBarService> cf = new WebChannelFactory<IFooBarService>("thirdparty"))
    {
        var channel = cf.CreateChannel();
        FooResponse result = channel.GetFoo("1234");
    }
}

Cuando ejecuto esto obtengo la siguiente excepción

No se puede deserializar el cuerpo XML con el nombre de la raíz 'respuesta' y el espacio de nombres raíz '' (para la operación 'getfoo' y contrato ('ifoobarservice', ','http://tempuri.org/')) usando XMLSerializer. Asegúrese de que el tipo correspondiente al XML se agregue a la colección de tipos conocida del servicio.

Si comento el GetBar operación de IFooBarService, funciona bien. Sé que me falta un concepto importante aquí, simplemente no sé qué buscar. ¿Cuál es la forma correcta de construir mis tipos de contrato, para que puedan ser deserializados adecuadamente?

¿Fue útil?

Solución

Diría que su servicio de terceros está muy roto. Aquí hay una colisión en el espacio de nombres: hay dos elementos nombrados response pero con diferentes tipos de esquema XML.

Creo que tendrá que no usar ninguna tecnología .NET que implique deserializar este XML. No habría forma de decirle a .NET en qué .NET tipo de .NET deserializar el XML.

Solo tendrás que hacerlo a mano. Linq a XML es útil para este propósito.

Otros consejos

Puede intentarlo con clase de respuesta como esta:

[XmlRoot("response")]
public class Response
{
    [XmlElement("foo")]
    public string Foo { get; set; }

    [XmlElement("bar")]
    public string Bar { get; set; }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top