Получение размера массива в JsonConverter - PullRequest
0 голосов
/ 22 января 2020

Если я использую конвертер json, похожий на очень грубый код, приведенный ниже, возможно ли получить размер массива, не переводя считыватель из начальной позиции? Или я могу сбросить его положение или клонировать читателя?

        public override object ReadJson(JsonReader reader, Type objectType,
            object existingValue, JsonSerializer serializer)
        {
            var jArray = JArray.Load(reader);
            int arrayLength = jArray.Count;
            return reader.Value;
        }

Обновление - ниже я добавил надуманный пример, если этот код будет запущен, вы увидите, что хотя роль помечена с помощью JsonRequired, она не проверка не пройдена из-за того, что читатель перемещается мимо этого значения в читателе. Может ли свойство глубины читателя дать мне то, что мне нужно?

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string json = @"{
                'Email': 'james@example.com',
                'Active': true,
                'CreatedDate': '2013-01-20T00:00:00Z',
                'Roles': [
                    {   
                        'Access': 'Write'
                    }
                 ]
            }";
            Account account = JsonConvert.DeserializeObject<Account>(json);

            Console.WriteLine(account.Email);
        }
    }

    public class Account
    {
        public string Email { get; set; }
        public bool Active { get; set; }
        public DateTime CreatedDate { get; set; }

        [JsonConverter(typeof(CustomMaximumListLengthConverter), 1)]
        public IList<Role> Roles { get; set; }
    }

    public class Role
    {
        [JsonRequired]
        public string RoleName { get; set; }
        public string Access { get; set; }
    }

    public class CustomMaximumListLengthConverter : JsonConverter
    {
        private readonly int _maxLength;

        public CustomMaximumListLengthConverter(int maxLength)
        {
            _maxLength = maxLength;
        }

        public override object ReadJson(JsonReader reader, Type objectType,
            object existingValue, JsonSerializer serializer)
        {

            var obj = JArray.Load(reader);
            if(obj.Count > _maxLength)
            {
                throw new JsonSerializationException("Too many items");
            }
            return reader.Value;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override bool CanConvert(Type objectType)
        {
            throw new NotImplementedException();
        }
    }
}

Я добавлю, что знаю, что могу проверить модель, используя ValidationContext et c, но я не хочу этого делать.

Кроме того, я понял, что reader.Value возвращает ноль, где, я думаю, я хочу вернуть IList, хотя это вызывает ошибку десериализации.

РЕДАКТИРОВАТЬ 2

После воспроизведения вокруг, кажется, ниже дает мне в основном то, что я ищу в грубом и готовом виде. Есть ли лучший подход?

        public override object ReadJson(JsonReader reader, Type objectType,
            object existingValue, JsonSerializer serializer)
        {
            var obj = JArray.Load(reader);
            if (obj.Count > _maxLength)
            {
                throw new JsonSerializationException("Too many items");
            }
            return obj.ToObject(objectType);
        }
...