c# - 重复序列化和反序列化创建重复项

标签 c# json serialization unity3d json.net

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

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

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

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

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

{
    "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 个单位。我哪里做错了?提前致谢

最佳答案

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

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

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

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

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

关于c# - 重复序列化和反序列化创建重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24835262/

相关文章:

c# - 如何以编程方式添加 DNS 别名?

Python 请求返回 JSON 解码器错误

javascript - jQuery AJAX 未输入 "success"

javascript - 更改 img 标签上的 src,无法使其工作

c# - 在 .NET 中将 List<object> 序列化为 XML 时如何重命名根节点?

python - 序列化和反序列化以及 Python RTree

c# - 更改 Gridview 页面后,Gridview 不会重新绑定(bind)数据

c# - 如何判断方法返回哪个接口(interface)

serialization - Spring MVC + jackson : Dynamic Json serialization

c# - 从 sql ExecuteScalar() 中检索值