防止Json.NET将字符串数组反序列化为键值对数组

本文关键字:数组 反序列化 键值对 字符串 Json NET 防止 | 更新日期: 2023-09-27 18:13:56

JsonConvert.DeserializeObject成功反序列化['a','b']List<KeyValuePair<string, object>>。我希望它失败,只有当输入字符串像[{'Key':'a','Value':'b'}]时才成功。

有办法做到这一点吗?

防止Json.NET将字符串数组反序列化为键值对数组

看来你可能已经发现了Json中的一个bug。. NET的KeyValuePairConverter,即它假设阅读器位于JSON对象的开头,而不是检查和验证它。如果你愿意,你可以报告一个问题。

同时,下面的JsonConverter将正确地抛出一个JsonException:

public class KeyValueConverter : JsonConverter
{
    interface IToKeyValuePair
    {
        object ToKeyValuePair();
    }
    struct Pair<TKey, TValue> : IToKeyValuePair
    {
        public TKey Key { get; set; }
        public TValue Value { get; set; }
        public object ToKeyValuePair()
        {
            return new KeyValuePair<TKey, TValue>(Key, Value);
        }
    }
    public override bool CanConvert(Type objectType)
    {
        bool isNullable = (Nullable.GetUnderlyingType(objectType) != null);
        Type type = (Nullable.GetUnderlyingType(objectType) ?? objectType);
        return type.IsGenericType
            && type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>);
    }
    public override bool CanWrite { get { return false; } } // Use Json.NET's writer.
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        bool isNullable = (Nullable.GetUnderlyingType(objectType) != null);
        Type type = (Nullable.GetUnderlyingType(objectType) ?? objectType);
        if (isNullable && reader.TokenType == JsonToken.Null)
            return null;
        if (type.IsGenericType
            && type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
        {
            var pairType = typeof(Pair<,>).MakeGenericType(type.GetGenericArguments());
            var pair = serializer.Deserialize(reader, pairType);
            if (pair == null)
                return null;
            return ((IToKeyValuePair)pair).ToKeyValuePair();
        }
        else
        {
            throw new JsonSerializationException("Invalid type: " + objectType);
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

然后像这样使用:

        string json = @"['a','b']";
        var settings = new JsonSerializerSettings { Converters = new JsonConverter[] { new KeyValueConverter() } };
        var list = JsonConvert.DeserializeObject<List<KeyValuePair<string, object>>>(json, settings);

小提琴例子。

当JSON包含不存在的属性时,使用JsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Error强制错误。

        var settings = new JsonSerializerSettings
        {
            MissingMemberHandling = MissingMemberHandling.Error,
            Converters = new JsonConverter[] { new KeyValueConverter() },
        };