Newtonsoft. json JsonConvert.SerializeObject - Сериализация только первого уровня - MaxDepth не работает для сериализации - PullRequest
1 голос
/ 06 апреля 2020

Мне нужно сериализовать только первый уровень объекта с помощью JsonConvert.SerializeObject. Я пробовал MaxDepth = 1, но это свойство только для десериализации.

Желаемое поведение (панель свойств отсутствует или имеет значение null):

class Foo
{
    public int First { get; set; } = 123;
    public string Second { get; set; } = "smurf";
    public DateTime Third { get; set; } = DateTime.Now;
    public Bar Bar { get; set; } = new Bar { Fourth = 999 };

}

class Bar
{
    public int Fourth { get; set; }
}

void Test(){
    var foo = new Foo();
    var jsonResult = JsonConvert.SerializeObject(foo);

    // jsonResult: 
    // {
    //    "First": 123,
    //    "Second": "smurf",
    //    "Third": "6.4. 2020 7:16",
    // }
}

Как настроить JsonConvert.SerializeObject игнорировать дочерние непримитивные объекты в сериализации? Большое спасибо.

1 Ответ

1 голос
/ 06 апреля 2020

Я нашел решение.

Я создал собственный JsonConverter:

    public class OnlyPrimitiveJsonConverter : JsonConverter
    {
        private readonly Type[] _types;

        public OnlyPrimitiveJsonConverter(params Type[] types)
        {
            _types = types;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            JToken t = JToken.FromObject(value, new JsonSerializer()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            });

            if (t.Type != JTokenType.Object)
            {
                t.WriteTo(writer);
            }
            else
            {
                JObject o = (JObject)t;

                var propertiesToRemove = new List<string>();

                foreach (var prop in value.GetType().GetProperties())
                {
                    if (
                        !prop.PropertyType.IsPrimitive &&
                        !prop.PropertyType.IsValueType &&
                        prop.PropertyType != typeof(string)
                        )
                    {
                        propertiesToRemove.Add(prop.Name);
                    }
                }

                foreach (var propToRemove in propertiesToRemove)
                {
                    o.Remove(propToRemove);
                }

                o.WriteTo(writer);
            }
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
        }

        public override bool CanRead
        {
            get { return false; }
        }

        public override bool CanConvert(Type objectType)
        {
            return _types.Any(t => t == objectType);
        }
    }

Я не заявляю о его безупречности, но он работает для меня. Он просто удаляет не примитивные и не оценочные типы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...