7

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

问题是当 JSON 返回并被序列化为我的一种自定义类型时,JSON 的一个位有时是一个数组,有时只是一个字符串。如果我的自定义类型有一个字符串,而 JSON 是一个数组,我会收到错误消息。如果 JSON 是一个对象并且我的自定义类型是一个数组,那么反过来也会发生同样的情况。它只是无法将其映射到属性。

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

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

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

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

如果它已经是一个数组,它应该不理会它。

转换器如下所示:

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(然而,'objecttype' 是一个 List)。

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

我认为我在正确的轨道上,但我需要朝着正确的方向轻推。我想我对 ReadJSon 方法的作用及其参数的含义有些困惑。

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

我对这个有点不了解。

4

2 回答 2

9

上周我不得不做类似的事情,我想出了以下内容,它适用于 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();
    }
于 2013-05-09T07:23:10.260 回答
3

我喜欢这种让 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);
    }
}
于 2013-12-17T20:00:07.710 回答