首页 > 解决方案 > 在 JsonConverter 中获取数组大小

问题描述

如果我正在运行类似于下面非常粗略的代码的 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;
        }

更新 - 如果运行此代码,我在下面添加了一个人为的示例,您会看到尽管 Role 被标记为 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 等验证模型,但我不想这样做。

另外,我已经意识到 reader.Value 在我想返回 IList 的地方返回 null,尽管这会引发反序列化错误。

编辑 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);
        }

标签: asp.net-web-apijson.netasp.net-core-webapiasp.net-core-2.2

解决方案


推荐阅读