我如何使用JSON.. NET处理一个值,该值有时是对象,有时是对象的数组

本文关键字:对象 数组 一个 JSON 何使用 NET 处理 | 更新日期: 2023-09-27 18:12:08

我注意到在stackoverflow上有一些其他的结果对于这个问题,但他们似乎不工作或模糊。使用最流行的结果,我把它们放在一起:

问题是,当JSON返回并被序列化为我的自定义类型之一时,JSON的其中一个位有时是数组,有时只是字符串。如果我的自定义类型有一个字符串,而JSON是一个数组,我会得到一个错误。反过来也是一样,如果JSON是对象,而我的自定义类型是数组。它只是不能映射到属性。

我决定解决这个问题,我想重写这个特定属性的反序列化,如果它是一个对象,我想把它转换成一个包含1个对象的数组。

在我序列化的对象中,我添加了一个JsonConverter,我认为它会覆盖它的反序列化方式。

[JsonConverter(typeof(ArrayOrSingleObjectConverter<string>))]
public List<string> person { get; set; }

这个想法是自定义转换器将单个对象转换为数组。因此,如果JSON是"Hello",它会将person设置为包含"Hello"的列表,而不是抛出一个异常,说不能将字符串转换为列表。

如果它已经是一个数组,它应该不去管它。

转换器如下所示:

public class ArrayOrSingleObjectConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true; // Not sure about this but technically it can accept an array or an object, so everything is game.
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (objectType == typeof(List<T>))
        {
            return serializer.Deserialize<List<T>>(reader);
        }
        else
        {
            var singleObject = serializer.Deserialize<T>(reader);
            var objectAsList = new List<T>();
            objectAsList.Add(singleObject);
            return objectAsList;
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

它不工作。上面的代码抛出了一个异常,试图反序列化单个字符串,表示它不能在if语句中将其强制转换为List(然而'objectype'是List)。

我正在努力理解读和写方法到底在做什么。在stackoverflow的另一个答案中,它建议在read方法中抛出一个NotImplementedException。但如果我这样做,read方法被调用,异常被抛出。

我想我的方向是对的,但我需要有人在正确的方向上轻轻一推。我想我对ReadJSon方法是做什么的和它的参数是什么意思有点困惑。

我真的不明白反序列化的值是从哪里来的,因为我没有在反序列化方法调用中指定它。

我对这件事有点不了解

我如何使用JSON.. NET处理一个值,该值有时是对象,有时是对象的数组

上周我不得不做类似的事情,我想出了下面的代码,它可以很好地用于List而不是数组

 internal class GenericListCreationJsonConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }
    public override bool CanRead
    {
        get { return true; }
    }
    public override bool CanWrite
    {
        get { return false; }
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.StartArray)
        {
            return serializer.Deserialize<List<T>>(reader);
        }
        else
        {
            T t = serializer.Deserialize<T>(reader);
            return new List<T>(new[] { t });
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

我喜欢这个生成Json的方法。NET做了所有繁重的工作。因此,它支持任何Json。. NET支持(List<>, ArrayList,强类型数组等)。

public class FlexibleCollectionConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.StartArray)
        {
            return serializer.Deserialize(reader, objectType);
        }
        var array = new JArray(JToken.ReadFrom(reader));
        return array.ToObject(objectType);
    }
    public override bool CanConvert(Type objectType)
    {
        return typeof (IEnumerable).IsAssignableFrom(objectType);
    }
}