重复序列化和反序列化会创建重复项

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

public class Database { public List armies { get; set;} public Database() { armies = new List(); armies.Add (new Army()); } } public class Army { public string faction { get; set;} public List army { get; set;} public Army() { faction = "RED"; army = new List(); 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 (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(www.text, settings); 

最好的方法是配置JSON.Net以替换默认值

 JsonSerializerSettings jsSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace, }; JsonConvert.DeserializeObject(jsonString, jsSettings);