我有以下课程:
public class TriGrid
{
private List<HexTile> _hexes;
//other private fields...
//other public proprerties
}
我的目标是仅序列化_hexes
字段,因此我创建了以下ContractResolver:
internal class TriGridContractResolver : DefaultContractResolver
{
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
return new List<MemberInfo> { objectType.GetMember("_hexes", BindingFlags.NonPublic | BindingFlags.Instance)[0] };
}
}
当我想序列化TriGrid的一个实例时,我做了:
var settings = new JsonSerializerSettings()
{
ContractResolver = new TriGridContractResolver()
};
var json = JsonConvert.SerializeObject(someTriGrid, settings);
string strintJson = json.ToString();
但是当我检查strintJson
的值始终为"{}"
时。 _hexes
有元素,不是空的。如果我序列化一个特定的HexTile
它按预期工作。我在这里做错了什么?
答案 0 :(得分:63)
无需实施自定义DefaultContractResolver
。解决方案是将[JsonProperty]
放在_hexes
上,[JsonIgnore]
放在所有其他属性和字段上。
答案 1 :(得分:5)
因为商业模式最终会发生变化,所以我更喜欢实施ISerializable并使用.NET创建游戏的方式(即属性包)。当您需要在运行时对对象进行版本化时,这最有效。任何你不想序列化的东西,都不要把它放在财产袋里。
特别是,因为JSON.Net(Newtonsoft.Json)也会通过序列化和反序列化方法来表达它。
using System;
using System.Runtime.Serialization;
[Serializable]
public class Visitor : ISerializable
{
private int Version;
public string Name { get; private set; }
public string IP { get; set: }
public Visitor()
{
this.Version = 2;
}
public void ChangeName(string Name)
{
this.Name = Name;
}
//Deserialize
protected Visitor(SerializationInfo info, StreamingContext context)
{
this.Version = info.GetInt32("Version");
this.Name = info.GetString("Name");
}
//Serialize
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Version", this.Version);
info.AddValue("Name", this.Name);
}
[OnDeserialized]
private void OnDeserialization(StreamingContext context)
{
switch (this.Version)
{
case 1:
//Handle versioning issues, if this
//deserialized version is one, so that
//it can play well once it's serialized as
//version two.
break;
}
}
}