XmlException: обнаружен непредвиденный символ '

Привет всем, я переключился на сериализацию Json, на этот раз сериализация работает отлично, проблема связана с десериализацией. У меня есть исключение ...

Ошибка:

XmlException: Encountered an unexpected character '
System.Xml.XmlExceptionHelper.ThrowXmlException (System.Xml.XmlDictionaryReader reader, System.Xml.XmlException exception) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.XmlJsonReader.Read () (at <3abed3971fab48b2a085712365cc627f>:0)
System.Xml.XmlBaseReader.ReadEndElement () (at <3abed3971fab48b2a085712365cc627f>:0)
System.Xml.XmlBaseReader.ReadElementContentAsString () (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlReaderDelegator.ReadElementContentAsString () (at <3abed3971fab48b2a085712365cc627f>:0)
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadValue (System.Type type, System.String name) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadMembers (System.Int32 index, System.Runtime.Serialization.ClassDataContract classContract, System.Runtime.Serialization.BitFlagsGenerator expectedElements, System.Int32& memberIndex) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadMembers (System.Runtime.Serialization.ClassDataContract classContract, System.Runtime.Serialization.ExtensionDataObject extensionData) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadClass (System.Runtime.Serialization.ClassDataContract classContract) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadFromJson (System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson context, System.Xml.XmlDictionaryString emptyDictionaryString, System.Xml.XmlDictionaryString[] memberNames) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderGenerator+CriticalHelper+<>c__DisplayClass0_0.<GenerateClassReader>b__0 (System.Runtime.Serialization.XmlReaderDelegator xr, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson ctx, System.Xml.XmlDictionaryString emptyDictionaryString, System.Xml.XmlDictionaryString[] memberNames) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonClassDataContract.ReadJsonValueCore (System.Runtime.Serialization.XmlReaderDelegator jsonReader, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson context) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonDataContract.ReadJsonValue (System.Runtime.Serialization.XmlReaderDelegator jsonReader, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson context) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadJsonValue (System.Runtime.Serialization.DataContract contract, System.Runtime.Serialization.XmlReaderDelegator reader, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson context) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson.ReadDataContractValue (System.Runtime.Serialization.DataContract dataContract, System.Runtime.Serialization.XmlReaderDelegator reader) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize (System.Runtime.Serialization.XmlReaderDelegator reader, System.String name, System.String ns, System.Type declaredType, System.Runtime.Serialization.DataContract& dataContract) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize (System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Type declaredType, System.Runtime.Serialization.DataContract dataContract, System.String name, System.String ns) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize (System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Type declaredType, System.Runtime.Serialization.DataContract dataContract, System.String name, System.String ns) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.DataContractJsonSerializer.InternalReadObject (System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Boolean verifyObjectName) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializer.InternalReadObject (System.Runtime.Serialization.XmlReaderDelegator reader, System.Boolean verifyObjectName, System.Runtime.Serialization.DataContractResolver dataContractResolver) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions (System.Runtime.Serialization.XmlReaderDelegator reader, System.Boolean verifyObjectName, System.Runtime.Serialization.DataContractResolver dataContractResolver) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions (System.Runtime.Serialization.XmlReaderDelegator reader, System.Boolean verifyObjectName) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject (System.Xml.XmlDictionaryReader reader) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject (System.IO.Stream stream) (at <3abed3971fab48b2a085712365cc627f>:0)
Server.Update () (at Assets/Scripts/Network/Server.cs:116)

код :

отправить функцию из клиентского класса:

public void sendToServer(NMSG msg, int channelId)
{

    if (!PacketHandler.packets.Contains(msg.GetType()))
    {
        Debug.Log("packet not registered");
        return;
    }

    byte error;
    byte[] buffer;
    var stream = new MemoryStream();
    var serializer = new DataContractJsonSerializer(typeof(NMSG));
    serializer.WriteObject(stream, msg);
    buffer = stream.ToArray();

    int bufferSize = buffer.Length;
    NetworkTransport.Send(hostId, connectionId, channelId, buffer, bufferSize, out error);
}

код, который десериализует:

MemoryStream memoryStream = new MemoryStream(recBuffer);
memoryStream.Position = 0;
var ser = new DataContractJsonSerializer(typeof(NMSG));
NMSG msg = (NMSG)ser.ReadObject(memoryStream);
onData(connectionId, channelId, recHostId, msg);

Класс НМСГ:

using System;
using System.Runtime.Serialization;

[DataContract]
[KnownType("GetKnownTypes")]
public abstract class NMSG
{
    [DataMember]
    private byte? discriminator = null;

    public NMSG()
    {

    }

    public NMSG(byte discriminator)
    {
        this.discriminator = discriminator;

    }

    public byte? getPacketId()
    {
        return this.discriminator;
    }

    public static Type[] GetKnownTypes()
    {
        return PacketHandler.packets.ToArray();
    }

    public abstract void HandleServer(NMSG msg, int connectionId);

    public abstract void HandleClient(NMSG msg);

}

класс, который я отправляю на сервер

[DataContract]
public class NMSG_ConnectAccount : NMSG
{
    [DataMember]
    public string username;
    [DataMember]
    public string password;

    public NMSG_ConnectAccount()
    {

    }

    public NMSG_ConnectAccount(string username, string password) : base((byte)PacketHandler.packets.IndexOf(typeof(NMSG_ConnectAccount)))
    {
        this.username = username;
        this.password = password;
    }


    public override void HandleClient(NMSG msg) 
    {

    }

    public override void HandleServer(NMSG msg, int connectionId)
    {
        NMSG_ConnectAccount cmsg = (NMSG_ConnectAccount)msg;
        Server server = Server.getServer();
        Mysql mysql = server.mysql;
        password = EncryptionUtils.MD5Hash(password);

        mysql.openMysqlConnection();

        MySqlCommand commandsql = new MySqlCommand("SELECT * FROM users WHERE username = '" + cmsg.username + "'", mysql.con);
        MySqlDataReader MyReader = commandsql.ExecuteReader();

        string activated = "";
        string mpassword = "";
        string muser = "";

        if (MyReader.Read())
        {
            activated = MyReader["confirmed"].ToString();
            mpassword = MyReader["password"].ToString();
            muser = MyReader["username"].ToString();
        }
        MyReader.Close();

        if (mpassword != cmsg.password || cmsg.username != muser)
        {
            server.sendToPlayer(new NMSG_ConnectionMessage(cmsg.username,false,false), server.reliableChannel, connectionId);
            return;
        }

        if (server.users.ContainsKey(connectionId))
            server.users[connectionId].setName(muser);
        else
            return;

        if (activated == "False")
        {
            server.sendToPlayer(new NMSG_ConnectionMessage(cmsg.username,false,true), server.reliableChannel, connectionId);
            return;
        }

        server.users[connectionId].pData = new PlayerData(cmsg.username);
        server.users[connectionId].isAuth = true;
        server.sendToPlayer(new NMSG_ConnectionMessage(cmsg.username,true,false), server.reliableChannel, connectionId);
    }

}

Заранее спасибо за вашу помощь


person NEOX    schedule 06.08.2019    source источник
comment
Вы пытаетесь десериализовать json с помощью сериализатора xml?   -  person Lasse V. Karlsen    schedule 06.08.2019
comment
Нет, это десериализатор json, посмотрите на код   -  person NEOX    schedule 06.08.2019
comment
Почему тогда вы получаете XmlException?   -  person Lasse V. Karlsen    schedule 06.08.2019
comment
Я не знаю, я поместил код, который я использовал для сериализации, выше   -  person NEOX    schedule 06.08.2019
comment
Не могли бы вы отредактировать свой вопрос, включив сведения об исключении в виде текста, а не в виде снимка экрана. ? Политика переполнения стека заключается в том, что вы должны включать свой код, сообщения об ошибках, сведения об исключениях и данные (JSON, XML и т. д.) в виде текста, а не изображения. Почему, см. Почему бы не загружать изображения кода на SO при задании вопроса и Не рекомендуется делать скриншоты кода и/или ошибок.   -  person dbc    schedule 07.08.2019
comment
@LasseVågsætherKarlsen - внутри DataContractJsonSerializer используется средство чтения, возвращенное JsonReaderWriterFactory.CreateJsonReader(), которое фактически наследуется от XmlReader и на лету переводит из JSON в XML. По-видимому, это было сделано для того, чтобы код десериализации Microsoft JSON мог повторно использовать как можно больше из десериализации контракта данных XML. Так что вполне возможно, что ОП может получить здесь XmlException.   -  person dbc    schedule 07.08.2019
comment
@NEOX - проверили ли вы с помощью отладки, что recBuffer содержит то же содержимое, что и buffer при отправке? Кроме того, это вопрос unity3d?   -  person dbc    schedule 07.08.2019
comment
Ну, тогда, возможно, есть проблема с JSON? Вы прогнали его через валидатор/линтер, убедились, что он действительно правильный?   -  person Lasse V. Karlsen    schedule 07.08.2019
comment
@dbc Звучит как абсолютно сумасшедшая реализация.   -  person Lasse V. Karlsen    schedule 07.08.2019
comment
Я надеюсь, что этот пароль и имя пользователя не настоящие? В противном случае вы должны немедленно изменить их.   -  person Lasse V. Karlsen    schedule 07.08.2019
comment
Это мой старый пароль, так что никаких проблем.   -  person NEOX    schedule 07.08.2019
comment
да, я использую unity3d после отладки потока. Я получаю это из журнала: данные отправлены на сервер: {__type: NMSG_ConnectAccount: #, дискриминатор: 5, пароль: abc, имя пользователя: INeoxz} полученные данные: {__type: NMSG_ConnectAccount: #, дискриминатор: 5,пароль:abc,имя пользователя:INeoxz}, но после отладки я получаю сообщение об ошибке SerializationException: ожидается элемент 'root' из пространства имен ''.. Встречается   -  person NEOX    schedule 07.08.2019
comment
Существуют ли классы NMSG_ConnectAccount и NMSG как на клиенте, так и на сервере? Если да, то находятся ли они в какой-то общей DLL, используемой обоими, или копируются локально в каждую из них?   -  person dbc    schedule 08.08.2019


Ответы (2)


это то, чем я занимаюсь :

класс packageHandler:

public class PacketHandler
{

    public static List<System.Type> packets = new List<System.Type>();

    public PacketHandler()
    {
        registerPacket(typeof(NMSG_CreatePlayer));
        registerPacket(typeof(NMSG_UpdatePlayer));
        registerPacket(typeof(NMSG_UpdatePlayerState));
        registerPacket(typeof(NMSG_CreateAccount));
        registerPacket(typeof(NMSG_RegisterMessage));
        registerPacket(typeof(NMSG_ConnectAccount));
        registerPacket(typeof(NMSG_ConnectionMessage));
        registerPacket(typeof(NMSG_ActivateAccountProcess));
        registerPacket(typeof(NMSG_DisconnectAccount));
        registerPacket(typeof(NMSG_PlayerDataTransmission));
        registerPacket(typeof(NMSG_UpdateAccountData));
        registerPacket(typeof(NMSG_UpdateInventory));
        registerPacket(typeof(NMSG_UpdateItemInventory));
        registerPacket(typeof(NMSG_RefreshShop));
        registerPacket(typeof(NMSG_BuyRequest));
    }

    public bool registerPacket(System.Type packet)
    {
        if(!packet.GetType().IsInstanceOfType(typeof(NMSG)))
        {
            throw new System.Exception("Type of packet must be NMSG");
        }
        if(packets.Count >= 256)
        {
            throw new System.Exception("Packets count exceed limit of 255");
        }
        if(packets.Contains(packet))
        {
            throw new System.Exception("Packet already registered");
        }
        packets.Add(packet);
        return true;
    }


}

Класс сервера

private void Start()
    {
        INSTANCE = this;
        NetworkSide.side = NetworkSide.Side.SERVER;

        mysql = new Mysql();
        if (!mysql.openMysqlConnection())
        {
            Debug.Log("ERROR- Server data center not active server closed...");
            return;
        }

        serverProperties = new ServerProperties();
        NetworkTransport.Init();
        ConnectionConfig cc = new ConnectionConfig();

        reliableChannel = cc.AddChannel(QosType.Reliable);
        unreliableChannel = cc.AddChannel(QosType.Unreliable);

        HostTopology topo = new HostTopology(cc, serverProperties.MAX_CONNECTION);
        hostId = NetworkTransport.AddHost(topo, serverProperties.port, null);

        packetHandler = new PacketHandler();

        registerCommand(new CommandHelp("help", "display all commands", null));
        registerCommand(new CommandGive("give", "give item to specified player", new string[] { "<Username>", "<ItemId>" }));
        registerCommand(new CommandStop("stop", "stop server", null));

        EventManager.registerEvent(new DeathEvent());
        EventManager.registerEvent(new AreaQuitEvent());
        EventManager.registerEvent(new AreaEnterEvent());
        EventManager.registerEvent(new DamageEvent());

        ItemInitializer.loadItems();

        world = new World();
        world.Load();

        Debug.Log("Server started in port : " + serverProperties.port);
        Debug.Log("Max Slot = " + serverProperties.MAX_CONNECTION);
        Debug.Log("You can configurate server data in serverProperties.properties");
        isStarted = true;
    }

как вы можете видеть, весь класс NMSG был значительно прописан в функции запуска

клиент:

    void Start()
    {
        client = this;
        packetHandler = new PacketHandler();
        NetworkSide.side = NetworkSide.Side.CLIENT;
        EventManager.registerEvent(new AreaQuitEvent());
        EventManager.registerEvent(new AreaEnterEvent());
        ConnectToServer("127.0.0.1",port);
    }

то же самое для клиента

теперь я буду отлаживать список "пакетов", чтобы увидеть, что он содержит

Консоль сервера:

packets count (Server) 15
NMSG_CreatePlayer
NMSG_UpdatePlayer
NMSG_UpdatePlayerState
NMSG_CreateAccount
NMSG_RegisterMessage
NMSG_ConnectAccount
NMSG_ConnectionMessage
NMSG_ActivateAccountProcess
NMSG_DisconnectAccount
NMSG_PlayerDataTransmission
NMSG_UpdateAccountData
NMSG_UpdateInventory
NMSG_UpdateItemInventory
NMSG_RefreshShop
NMSG_BuyRequest

UnityEngine.Debug:Log(Object)
Server:Start() (at Assets/Scripts/Network/Server.cs:90)

Консоль клиента:

packets count (Client) 15
NMSG_CreatePlayer
NMSG_UpdatePlayer
NMSG_UpdatePlayerState
NMSG_CreateAccount
NMSG_RegisterMessage
NMSG_ConnectAccount
NMSG_ConnectionMessage
NMSG_ActivateAccountProcess
NMSG_DisconnectAccount
NMSG_PlayerDataTransmission
NMSG_UpdateAccountData
NMSG_UpdateInventory
NMSG_UpdateItemInventory
NMSG_RefreshShop
NMSG_BuyRequest

UnityEngine.Debug:Log(Object)
Client:Start() (at Assets/Scripts/Network/Client.cs:64)

так что не может быть, чтобы список пакетов был пуст, я не понимаю, почему это не работает...

person NEOX    schedule 08.08.2019
comment
Вы должны добавить это к своему вопросу, а не добавлять его в качестве ответа. См.: meta.stackoverflow.com/questions/265552/ - person dbc; 08.08.2019

Проблема решена Теперь я использую ручную сериализацию, которая намного быстрее и занимает меньше места. Я рекомендую этот метод всем, кто использует сериализацию для отправки сетевых объектов.

person NEOX    schedule 10.08.2019