XmlException: отсутствует элемент Root. C# Единство - PullRequest
0 голосов
/ 13 июля 2020

Я пытаюсь отправить list<clase_A> по xmlSerializer из интерфейса в единицу.

Вот мой код сервера:

using (connectedTcpClient = tcpListener.AcceptTcpClient())
            {               
                using (NetworkStream stream = connectedTcpClient.GetStream())
                {
                    int length;
                    XmlSerializer xmls = new XmlSerializer(typeof(List<Clase_comando>));
                                        
                    while ((stream.CanRead && (length = stream.Read(bytes, 0, bytes.Length)) != 0))
                    {
                        List<Clase_comando> com = null;
                        var b = new byte[10000];                                                      
                        com = (List<Clase_comando>)xmls.Deserialize(stream);
                            //Here i get the problem
                        

                    }
                }
            }

Вот код Visual Studio:

NetworkStream stream = socketConnection.GetStream();
StreamWriter sw = new StreamWriter(stream);
sw.AutoFlush = true;
XmlSerializer xmls = new XmlSerializer(typeof(List<Clase_A>));

if (stream.CanWrite){
   z = My list

   byte[] b = new byte[10000];
   Stream st = new MemoryStream(b);
   xmls.Serialize(st, z);
   stream.Write(b, 0, b.Length);
   stream.Dispose();
   }

Проблема в том, что когда я получаю данные интерфейса в единстве, возникает это исключение:

XmlException: Root element is missing.  
System.Xml.XmlTextReaderImpl.Throw (System.Exception e) (at <7fd195060d8c41448694ab221d3b56ca>:0)  
System.Xml.XmlTextReaderImpl.ThrowWithoutLineInfo (System.String res) (at <7fd195060d8c41448694ab221d3b56ca>:0)

Ответы [ 2 ]

0 голосов
/ 14 июля 2020

В этой строке

while ((stream.CanRead && (length = stream.Read(bytes, 0, bytes.Length)) != 0))

данные читаются из stream в bytes. После этого либо данные в потоке отсутствуют, либо root уже отсутствует. Итак, в следующей строке сериализатор читает из поврежденного потока:

com = (List<Clase_comando>)xmls.Deserialize(stream);

Попробуйте этот код:

using (NetworkStream stream = connectedTcpClient.GetStream())
{
    var xmls = new XmlSerializer(typeof(List<Clase_comando>));
            
    var com = (List<Clase_comando>)xmls.Deserialize(stream);
}
0 голосов
/ 13 июля 2020

Afaik, вы не можете напрямую (де) сериализовать в List<T>.

Вам скорее понадобится класс-оболочка, например

[Serializable]
[XmlRoot]
public class Root
{
    [XmlArray]
    public List<Clase_comando> Comandos;
}

и

using (NetworkStream stream = connectedTcpClient.GetStream())
{
    int length;
    XmlSerializer xmls = new XmlSerializer(typeof(Root));
                                    
    while ((stream.CanRead && (length = stream.Read(bytes, 0, bytes.Length)) != 0))
    {
        var b = new byte[10000];                                                      
        List<Clase_comando> com = ((Root)xmls.Deserialize(stream)).Comandos;                    
    }
}

А с другой стороны соответственно

[Serializable]
[XmlRoot]
public class Root
{
    [XmlArray]
    public List<Clase_A> Comandos;
}

и

XmlSerializer xmls = new XmlSerializer(typeof(Root));

if (stream.CanWrite)
{
    var root = new Root(){ Comandos = MyList };

    byte[] b = new byte[10000];
    using(var st = new MemoryStream(b))
    {
        xmls.Serialize(st, root);
        stream.Write(b, 0, b.Length);
    }
}

Набрано на смартфоне, но надеюсь, что идея прояснится

...