重复序列化和反序列化创建重复项 [英] Repeated serialization and deserialization creates duplicate items

查看:42
本文介绍了重复序列化和反序列化创建重复项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我的 json serealization 有问题.我在 Unity 下使用 Json.NET 包:我正在搜索创建一个数据库,可在我的应用程序上编辑并通过 wwwForm 和 php 文件存储在我的服务器上.我可以毫无问题地创建它并将其推送到网上.问题是,当我加载它时,数据库最后有一个新条目.数据库类是这样的:

Hi everyone i have a problem with my json serealization. I'm using the Json.NET package under Unity: I'm searching to make a Database, editable on my application and stored on my server through wwwForm and a php file. I have no problem to create it and to push it on the net. The problem is, when i load it, the database has a new entry at the end. The Database Class is this:

public class Database   {
    public List<Army> armies { get; set;}

    public Database() {
        armies = new List<Army>();
        armies.Add (new Army());
    }
}

public class Army
{
    public string faction { get; set;}
    public List<Unit> army { get; set;}

    public Army()
    {
        faction = "RED";
        army = new List<Unit>();
        army.Add (new Unit());
    }
}

public class Unit
{
    public string name { get; set;}
    public float fissionTimer { get; set;}
    public float HP { get; set;}
    public int shield { get; set;}
    public float strenght { get; set;}
    public float movSpeed { get; set;}
    public float attackSpeed { get; set;}
    public float farmAggro { get; set;}
    public int criticPossibility { get; set;}
    public int armorPenetration { get; set;}
    public bool isContagious { get; set;}
    public int contagePossibility { get; set;}
    public string imgName {get;set;}

    public Unit()
    {
        name = "standard";
        fissionTimer = 8;
        HP = 100;
        shield = 0;
        strenght = 10;
        movSpeed = 5;
        attackSpeed = 0.1f;
        farmAggro = 0.1f;
        criticPossibility = 0;
        armorPenetration = 0;
        isContagious = false;
        contagePossibility = 0;
        imgName = "Red";
    } 

    public Unit(string _name, float _fissionTimer, float _HP, int _shield, float _strenght, float _movSpeed, float _attackSpeed, 
                float _farmAggro, int _criticPossibility, int _armorPen, bool _iscontagious, int _contagePos, string _imgName)
    {
        name = _name;
        fissionTimer = _fissionTimer;
        HP = _HP;
        shield = _shield;
        strenght = _strenght;
        movSpeed = _movSpeed;
        attackSpeed = _attackSpeed;
        farmAggro = _farmAggro;
        criticPossibility = _criticPossibility;
        armorPenetration = _armorPen;
        isContagious = _iscontagious;
        contagePossibility = _contagePos;
        imgName = _imgName;
    }
}

序列化和反序列化我使用这两种方法:

to serialize and deserialize i use those 2 methods:

IEnumerator LoadFile()
{
    WWW www = new WWW(dbPath);

    yield return www;

    var _database = JsonConvert.DeserializeObject<Database> (www.text);

    db = _database;
    SendMessage ("loaded", SendMessageOptions.DontRequireReceiver);
}

IEnumerator SaveFile(Database db)
{
    WWWForm form = new WWWForm();
    string serialized = JsonConvert.SerializeObject (db);
    form.AddField("theDatabase", serialized);

    WWW www = new WWW(phpPath, form);

    yield return www;

    if (www.error == null)
        Debug.Log ("saved" + serialized);
    else
        Debug.LogError ("error saving database");
}

使用默认构造函数,序列化和反序列化的结果是这样的:

The result of using the default constructor, serialized and deserialized is this:

{
    "armies": [
        {
            "faction": "RED",
            "army": [
                {
                    "name": "standard",
                    "fissionTimer": 8,
                    "HP": 100,
                    "shield": 0,
                    "strenght": 10,
                    "movSpeed": 5,
                    "attackSpeed": 0.1,
                    "farmAggro": 0.1,
                    "criticPossibility": 0,
                    "armorPenetration": 0,
                    "isContagious": false,
                    "contagePossibility": 0,
                    "imgName": "Red"
                }
            ]
        },
        {
            "faction": "RED",
            "army": [
                {
                    "name": "standard",
                    "fissionTimer": 8,
                    "HP": 100,
                    "shield": 0,
                    "strenght": 10,
                    "movSpeed": 5,
                    "attackSpeed": 0.1,
                    "farmAggro": 0.1,
                    "criticPossibility": 0,
                    "armorPenetration": 0,
                    "isContagious": false,
                    "contagePossibility": 0,
                    "imgName": "Red"
                }
            ]
        }
    ]
}

有 2 个军队和 2 个单位.我哪里做错了?提前致谢

There are 2 armies and 2 units. Where i am doing wrong? Thanks in advance

推荐答案

发生这种情况的原因是两件事的结合:

The reason this is happening is due to the combination of two things:

  1. 您的类构造函数会自动将默认项添加到它们各自的列表中.Json.Net 在反序列化期间调用这些相同的构造函数来创建对象实例.
  2. Json.Net 的默认行为是在反序列化期间重用(即添加到)现有列表,而不是替换它们.

要解决此问题,您可以更改代码,使构造函数不会自动将默认项添加到列表中,或者您可以配置 Json.Net 以在反序列化时替换列表,而不是重用它们.后者可以通过更改 ObjectCreationHandling设置为Replace如下图:

To fix this, you can either change your code such that your constructors do not automatically add default items to your lists, or you can configure Json.Net to replace the lists on deserialization rather than reusing them. The latter by can be done by changing the ObjectCreationHandling setting to Replace as shown below:

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ObjectCreationHandling = ObjectCreationHandling.Replace;

var database = JsonConvert.DeserializeObject<Database>(www.text, settings);

这篇关于重复序列化和反序列化创建重复项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆