XmlException:遇到意外字符'

时间:2019-08-06 16:01:27

标签: c# json serialization datacontractjsonserializer

大家好,我改用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);

NMSG类别:

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

}

预先感谢您的帮助

2 个答案:

答案 0 :(得分:0)

这就是我要做的:

packetHandler类:

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)

所以数据包列表包含的内容不可能为空,我不明白为什么它不起作用...

答案 1 :(得分:0)

问题解决了,我现在使用的是手动序列化,它更快,占用空间更少,我向所有使用序列化发送网络对象的人推荐这种方法。