Ответ 1
Нет необходимости реализовывать пользовательский DefaultContractResolver
. Решение состоит в том, чтобы положить [JsonProperty]
на _hexes
и [JsonIgnore]
на все остальные свойства и поля.
У меня есть следующий класс:
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
, он работает так, как ожидалось. Что я здесь делаю неправильно?
Нет необходимости реализовывать пользовательский DefaultContractResolver
. Решение состоит в том, чтобы положить [JsonProperty]
на _hexes
и [JsonIgnore]
на все остальные свойства и поля.
Поскольку бизнес-модели в конечном итоге меняются, я предпочитаю внедрять 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 serialized as
//version two.
break;
}
}
}