Reputation: 2791
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?
Upvotes: 64
Views: 68181
Reputation: 368
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;
}
}
}
Upvotes: 12
Reputation: 2791
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.
Upvotes: 136