Json.net serialize specific private field

C#Serializationjson.net

C# Problem Overview


I have the following class:

public class TriGrid
{
    private List<HexTile> _hexes;
    //other private fields...
    //other public proprerties
}

My goal is to serialize only the _hexes field, so I created the following ContractResolver:

internal class TriGridContractResolver : DefaultContractResolver
{
    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    {
        return new List<MemberInfo> { objectType.GetMember("_hexes", BindingFlags.NonPublic | BindingFlags.Instance)[0] };
    }
}

and when I want to serialize an instance of TriGrid I do:

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

but when I check the value of strintJson is always "{}". The _hexes has elements, it is not empty. If I serialize one particular HexTile it works as expected. What I am doing wrong here?

C# Solutions


Solution 1 - C#

There is no need to implement a custom DefaultContractResolver. The solution is to put [JsonProperty] on _hexes and [JsonIgnore] on all the other properties and fields.

Solution 2 - C#

Because business models will eventually change, I prefer implementing ISerializable and using .NET's way of creating momentos (i.e., a property bag). This works best when you need to version your objects at runtime. Anything that you don't want to serialize, don't put it in the property bag.

Especially, since JSON.Net (Newtonsoft.Json) will also honor it with its serialization and deserialization methods.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBsa0View Question on Stackoverflow
Solution 1 - C#Bsa0View Answer on Stackoverflow
Solution 2 - C#Roy OliverView Answer on Stackoverflow