简体   繁体   English

XMLSerializer正确序列化,但是在反序列化时抛出TargetInvocationException

[英]XMLSerializer serializes correctly, but throws TargetInvocationException when deserialzing

I'm making an inventory system for a Unity game. 我正在为Unity游戏制作库存系统。

It serializes and saves the inventory to an xml file as expected; 它将序列化并将清单按预期方式保存到xml文件中; However, when I deserialize, the items are set to null and a TargetInvocationException is thrown; 但是,当我反序列化时,这些项目设置为null并抛出TargetInvocationException and ultimately a NullReferenceException . 最后是NullReferenceException


What am I doing wrong? 我究竟做错了什么?


Serialize and Deserialize Methods 序列化和反序列化方法

public void SaveInventoryToXML()
{
    System.Xml.Serialization.XmlSerializer writer = new System.Xml.Serialization.XmlSerializer(typeof (List<Item>));
    System.IO.StreamWriter file = new System.IO.StreamWriter(inventoryPath);
    writer.Serialize(file, inventory);
    file.Close();
}

public void LoadInventoryFromXML()
{
    System.Xml.Serialization.XmlSerializer reader = new System.Xml.Serialization.XmlSerializer(typeof(List<Item>));
    StreamReader sr = new StreamReader(inventoryPath);
    inventory = (List<Item>) reader.Deserialize(sr);
    sr.Close();
}

'Item' & 'Enchantment' Class '物品'和'附魔'等级

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

[System.Serializable] //what's with the square brackets
public class Item
{
    public string ItemName;
    public int ItemId;
    public string ItemDesc;
    public int BaseWorth;
    public int BaseDamage;
    public int RequiredLevel;
    public Sprite Sprite;
    public ItemType itemType;
    public ItemRarity itemRarity;
    public Weapon.WeaponType weaponType;
    public Weapon.AttackType attackType;
    public List<Enchantment> Enchantments;
    public bool Stackable;
    public int StackSize = 99;
    public int Amount = 1;

    public enum ItemType
    {
        Weapon, Consumable, Quest, Armor, Boots, Helmet, Gloves, Ring, Amulet
    }

    public enum ItemRarity
    {
        Common, Rare, Unique, Magic
    }

    public Item(string name, int id, int reqlvl, string desc, int baseworth, int basedamage, List<Enchantment> enchantments, ItemType itemtype, ItemRarity itemrarity, Sprite sprite )
    {
        ItemName = name;
        ItemId = id;
        RequiredLevel = reqlvl;
        ItemDesc = desc;
        BaseWorth = baseworth;
        BaseDamage = basedamage;
        Enchantments = enchantments;
        itemType = itemtype;
        itemRarity = itemrarity;
        Sprite = sprite;
        additionalParameters();
    }

    private void additionalParameters()
    {
        switch (itemType)
        {
            case ItemType.Consumable:
                Stackable = true;
                break;
        }
    }

    public Item()
    {
        ItemId = -1;
    }
}

public class Enchantment
{
    public EnchantmentType Type;
    public int Amount;
    public enum EnchantmentType
    {
        Fire, Ice, Poison, Electric, Brutalize, Greed, Invisiblity, Heal, ReplenishStamina, ReplenishMana,
        AddMaxHealth, AddMaxStamina, AddMaxMana
    }

    public Enchantment(EnchantmentType type, int amount)
    {
        Amount = amount;
        Type = type;
    }

    public Enchantment()
    {

    }
}

Call Stack 调用堆栈

NullReferenceException
System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:232)
System.Reflection.MonoProperty.SetValue (System.Object obj, System.Object value, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] index, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoProperty.cs:348)
System.Reflection.PropertyInfo.SetValue (System.Object obj, System.Object value, System.Object[] index) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/PropertyInfo.cs:102)
System.Xml.Serialization.XmlTypeMapMember.SetValue (System.Object ob, System.Object value)
System.Xml.Serialization.XmlSerializationReaderInterpreter.SetMemberValue (System.Xml.Serialization.XmlTypeMapMember member, System.Object ob, System.Object value, Boolean isValueList)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadMembers (System.Xml.Serialization.ClassMap map, System.Object ob, Boolean isValueList, Boolean readByOrder)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadClassInstanceMembers (System.Xml.Serialization.XmlTypeMapping typeMap, System.Object ob)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadClassInstance (System.Xml.Serialization.XmlTypeMapping typeMap, Boolean isNullable, Boolean checkType)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadObject (System.Xml.Serialization.XmlTypeMapping typeMap, Boolean isNullable, Boolean checkType)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadObjectElement (System.Xml.Serialization.XmlTypeMapElementInfo elem)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadMembers (System.Xml.Serialization.ClassMap map, System.Object ob, Boolean isValueList, Boolean readByOrder)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadClassInstanceMembers (System.Xml.Serialization.XmlTypeMapping typeMap, System.Object ob)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadClassInstance (System.Xml.Serialization.XmlTypeMapping typeMap, Boolean isNullable, Boolean checkType)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadObject (System.Xml.Serialization.XmlTypeMapping typeMap, Boolean isNullable, Boolean checkType)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadObjectElement (System.Xml.Serialization.XmlTypeMapElementInfo elem)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadListElement (System.Xml.Serialization.XmlTypeMapping typeMap, Boolean isNullable, System.Object list, Boolean canCreateInstance)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadObject (System.Xml.Serialization.XmlTypeMapping typeMap, Boolean isNullable, Boolean checkType)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadRoot (System.Xml.Serialization.XmlTypeMapping rootMap)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadRoot ()
System.Xml.Serialization.XmlSerializer.Deserialize (System.Xml.Serialization.XmlSerializationReader reader)

writer.Serializer writer.Serializer

sampled output 采样 输出

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Item>
        <ItemName>Steel Sword</ItemName>
        <ItemId>102</ItemId>
        <ItemDesc>A fine steel sword.</ItemDesc>
        <BaseWorth>125</BaseWorth>
        <BaseDamage>25</BaseDamage>
        <RequiredLevel>10</RequiredLevel>
        <Sprite>
            <name>BasicWeapons_2</name>
            <hideFlags>NotEditable</hideFlags>
        </Sprite>
        <itemType>Weapon</itemType>
        <itemRarity>Rare</itemRarity>
        <weaponType>Sword</weaponType>
        <attackType>Swing</attackType>
        <Stackable>false</Stackable>
        <StackSize>99</StackSize>
        <Amount>1</Amount>
    </Item>
    <Item>
        <ItemName>Mithril Sword</ItemName>
        <ItemId>103</ItemId>
        <ItemDesc>Feels lighter than steel, yet much sharper...</ItemDesc>
        <BaseWorth>625</BaseWorth>
        <BaseDamage>125</BaseDamage>
        <RequiredLevel>25</RequiredLevel>
        <Sprite>
            <name>BasicWeapons_3</name>
            <hideFlags>NotEditable</hideFlags>
        </Sprite>
        <itemType>Weapon</itemType>
        <itemRarity>Unique</itemRarity>
        <weaponType>Sword</weaponType>
        <attackType>Swing</attackType>
        <Stackable>false</Stackable>
        <StackSize>99</StackSize>
        <Amount>1</Amount>
    </Item>
    <Item>
        <ItemId>-1</ItemId>
        <BaseWorth>0</BaseWorth>
        <BaseDamage>0</BaseDamage>
        <RequiredLevel>0</RequiredLevel>
        <itemType>Weapon</itemType>
        <itemRarity>Common</itemRarity>
        <weaponType>Sword</weaponType>
        <attackType>Swing</attackType>
        <Stackable>false</Stackable>
        <StackSize>99</StackSize>
        <Amount>1</Amount>
    </Item>
</ArrayOfItem>

File: http://a.pomf.se/avxuvz.xml 档案: http//a.pomf.se/avxuvz.xml

I've just tried your code myself and I managed to get it working properly by removing the Sprite field. 我刚刚亲自尝试了您的代码,并通过删除Sprite字段设法使其正常工作。 My guess is that this is your culprit, as it most likely cannot be serialized - so you may have to simply store the path to the sprite as a string or something similar. 我的猜测是这是您的罪魁祸首,因为它很可能无法序列化-因此您可能必须简单地将指向sprite的路径存储为string或类似形式。

var list = new List<Item>()
{
    new Item(),
    new Item()
};
var xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(List<Item>));

using (var stream = File.Open("Document.xml", FileMode.CreateNew))
{
    xmlSerializer.Serialize(stream, list);
}

using (var stream = File.Open("Document.xml", FileMode.Open))
{
    xmlSerializer.Deserialize(stream);
}

Produces the following output: 产生以下输出:

<?xml version="1.0"?>
<ArrayOfItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Item>
    <ItemId>-1</ItemId>
    <BaseWorth>0</BaseWorth>
    <BaseDamage>0</BaseDamage>
    <RequiredLevel>0</RequiredLevel>
    <itemType>Weapon</itemType>
    <itemRarity>Common</itemRarity>
    <Stackable>false</Stackable>
    <StackSize>99</StackSize>
    <Amount>1</Amount>
  </Item>
  <Item>
    <ItemId>-1</ItemId>
    <BaseWorth>0</BaseWorth>
    <BaseDamage>0</BaseDamage>
    <RequiredLevel>0</RequiredLevel>
    <itemType>Weapon</itemType>
    <itemRarity>Common</itemRarity>
    <Stackable>false</Stackable>
    <StackSize>99</StackSize>
    <Amount>1</Amount>
  </Item>
</ArrayOfItem>

显然手动进行并不有趣,但是您可以尝试通过IXmlSerializable进行序列化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 创建XmlSerializer正确序列化/反序列化派生类型 - Creating XmlSerializer that serializes/deserializes derived types correctly 发现相同的字段名称时,使用javascriptserializer反序列化会引发异常 - Deserialzing with javascriptserializer throws exception when found same field name 使用 WebClient DownloadStringAsync 下载时抛出 TargetInvocationException - Throws TargetInvocationException when downloading with WebClient DownloadStringAsync XmlSerializer 序列化但不反序列化 - XmlSerializer serializes but doesn't deserialize XmlSerializer 将 float 序列化为 1E+07 - XmlSerializer serializes float as 1E+07 反序列化JSON会引发TargetInvocationException - Deserializing JSON throws TargetInvocationException 事件和IPCServerChannel引发TargetInvocationException - Events and IPCServerChannel throws TargetInvocationException WPF调度程序抛出TargetInvocationException - WPF Dispatcher throws TargetInvocationException 更改XmlSerializer序列化空元素的方式 - change how XmlSerializer serializes empty elements 序列化List的XmlSerializer的构造函数 <T> 与XmlAttributeOverrides一起使用时抛出InvalidOperationException - Constructor of a XmlSerializer serializing a List<T> throws an InvalidOperationException when used with XmlAttributeOverrides
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM