Json.net序列化特定的私有字段

Bsa*_*sa0 30 c# serialization json.net

我有以下课程:

public class TriGrid
{
    private List<HexTile> _hexes;
    //other private fields...
    //other public proprerties
}
Run Code Online (Sandbox Code Playgroud)

我的目标是仅序列化_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] };
    }
}
Run Code Online (Sandbox Code Playgroud)

当我想序列化TriGrid的一个实例时,我做了:

var settings = new JsonSerializerSettings()
{
    ContractResolver = new TriGridContractResolver()
};
var json = JsonConvert.SerializeObject(someTriGrid, settings);
string strintJson = json.ToString();
Run Code Online (Sandbox Code Playgroud)

但当我检查的价值strintJson总是"{}".该_hexes具有的元素,它不是空的.如果我序列化一个特定的HexTile它按预期工作.我在这做错了什么?

Bsa*_*sa0 76

无需实现自定义DefaultContractResolver.解决的办法是把[JsonProperty]上_hexes和[JsonIgnore]所有其他属性和领域.

  • 也可以在类上使用[`[JsonObject(MemberSerialization.OptIn)]`](http://www.newtonsoft.com/json/help/html/JsonObjectAttributeOptIn.htm).这样``[JsonIgnore]`属性变得不必要了. (23认同)

Roy*_*ver 6

因为商业模式最终会发生变化,所以我更喜欢实现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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)