Antes de escribir esta pregunta, probé this, this y este método. Pasé todo el día en eso y no pude obtener el resultado.

Tengo mi propia API REST que devuelve un List<T> serializado en un archivo XML

    [ActionName("planes")]
    [HttpGet]
    public IEnumerable<Planes> GetPlanes()
    {
        using (DB_A5vehiclesEntities entities = new DB_A5_vehiclesEntities())
        {
            return entities.Planes.ToList();
        }
    }

El archivo XML generado se ve así (enlace al archivo xml):

<ArrayOfPlanes xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/VehicleDataAccess">
  <Planes>
    <FirstFlyYear>1932</FirstFlyYear>
    <Id>18</Id>
    <Name>18</Name>
    //other values
</Planes>
//other items

Mi código:

IList<Plane> myList = null;

        string xml = @"http://bo7145907-001-site2.ftempurl.com/wtvapi/vehicles/planes";
        XmlSerializer serializer = new XmlSerializer(typeof(List<Plane>));
        using (StringReader reader = new StringReader(xml))
        {

            myList = serializer.Deserialize(reader) as List<Plane>;
        }

        textMessage = FindViewById<TextView>(Resource.Id.message);

    }

Y recibo el error: System.Xml.XmlException: 'Los datos en el nivel raíz no son válidos. Línea 1, posición 1

Todo lo que quiero es conectarme a la API, deserializar XML y obtener List<T> con todos los elementos XML. ¿Cómo hacerlo bien?

0
Bogdan Ilkiv 26 jun. 2020 a las 00:27

3 respuestas

Puede agregar la clase Root que tenga una lista de Planes, como el siguiente código:
1 - clase ArrayOfPlanes:

[XmlRoot(ElementName = "ArrayOfPlanes", Namespace = "http://schemas.datacontract.org/2004/07/VehicleDataAccess")]
public class ArrayOfPlanes
{
    [XmlElement(ElementName = "Planes", Namespace = "http://schemas.datacontract.org/2004/07/VehicleDataAccess")]
    public List<Plane> Planes { get; set; }
}

[XmlRoot(ElementName = "Planes", Namespace = "http://schemas.datacontract.org/2004/07/VehicleDataAccess")]
public class Plane
{
....
}

2 - Cambia poco el código a:

IList<Plane> myList = null;
XmlSerializer serializer = new XmlSerializer(typeof(ArrayOfPlanes));
using (StringReader reader = new StringReader(xml))
{

    ArrayOfPlanes arrayOfPlanes = serializer.Deserialize(reader) as ArrayOfPlanes;
    myList = arrayOfPlanes?.Planes;
}

Espero que encuentres esto útil.

0
Sajid 25 jun. 2020 a las 22:52

El uso de HttpClient proporciona un código conciso y eficiente.

string url = "http://bo7145907-001-site2.ftempurl.com/wtvapi/vehicles/planes";
var serializer = new XmlSerializer(typeof(ArrayOfPlanes));
ArrayOfPlanes arrayOfPlanes;

using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.Add("Accept", "text/xml");

    using (var stream = await client.GetStreamAsync(url))
    {
        arrayOfPlanes = (ArrayOfPlanes)serializer.Deserialize(stream);
    }
}

Conjunto de clases

[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/VehicleDataAccess")]
public class ArrayOfPlanes
{
    [XmlElement(Namespace = "http://schemas.datacontract.org/2004/07/VehicleDataAccess")]
    public List<Planes> Planes { get; set; }
}

public class Planes
{
    public bool AAMissile { get; set; }
    // ...
}
0
Alexander Petrov 26 jun. 2020 a las 00:56

Intenta lo siguiente:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        const string URL = "http://bo7145907-001-site2.ftempurl.com/wtvapi/vehicles/planes";
        static void Main(string[] args)
        {

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);
            request.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US\r\n");
            request.UserAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36\r\n";
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n";

            WebResponse response = request.GetResponse();

            XmlReader xReader = XmlReader.Create(response.GetResponseStream());

            XmlSerializer serializer = new XmlSerializer(typeof(ArrayOfPlanes));
            ArrayOfPlanes planes = (ArrayOfPlanes)serializer.Deserialize(xReader);
 
        }
    }
    [XmlRoot(ElementName = "ArrayOfPlanes", Namespace = "http://schemas.datacontract.org/2004/07/VehicleDataAccess")]
    public class ArrayOfPlanes
    {
        [XmlElement(ElementName = "Planes", Namespace = "http://schemas.datacontract.org/2004/07/VehicleDataAccess")]
        public List<Planes> Plains { get; set; }
    }
    public class Planes
    {
    }
}
0
jdweng 26 jun. 2020 a las 00:01