Подтвердить что ты не робот

Json.net сериализует определенное частное поле

У меня есть следующий класс:

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, он работает так, как ожидалось. Что я здесь делаю неправильно?

4b9b3361

Ответ 1

Нет необходимости реализовывать пользовательский DefaultContractResolver. Решение состоит в том, чтобы положить [JsonProperty] на _hexes и [JsonIgnore] на все остальные свойства и поля.

Ответ 2

Поскольку бизнес-модели в конечном итоге меняются, я предпочитаю внедрять 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;
        }
    }
}