如何在提供对象类型时告诉JSON.NET将JArray反序列化为List <object>?

时间:2015-06-29 15:07:42

标签: c# .net json json.net

我们有以下课程:

[dtFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

此类接受字段class Foo { public object Any; } 中的任何内容。

我打电话的时候:

Any

JsonConvert.DeserializeObject<Foo>("{any: 5}") 包含Any

然而,当我打电话时:

System.Int64

JsonConvert.DeserializeObject<Foo>("{any: [5]}") 包含Any

如何配置JSON.NET,以便在这种情况下Newtonsoft.Json.Linq.JArray包含Any

澄清:

可以有任何东西,我可以打电话:

List<object>

JsonConvert.DeserializeObject<Foo>("{any: 'c'}")

更多说明:

我想告诉JSON.NET(可能使用JsonSerializerSettings):

  

当您遇到JsonConvert.DeserializeObject<Foo>("{any: ['c', 5]}") 并且JSON包含数组时,请反序列化该数组   (例如)object

3 个答案:

答案 0 :(得分:2)

您的回答可能是here

您的[5]是一个数组。您所要做的就是将其投射到列表中。

您也可以创建自己的转换器,例如described here

答案 1 :(得分:2)

目前,我已经嘲笑了以下解决方案:

public class MyObjectConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(object);
    }

    public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        switch (reader.TokenType)
        {
            case Newtonsoft.Json.JsonToken.StartArray:
                return JToken.Load(reader).ToObject<List<object>>(); 
            case Newtonsoft.Json.JsonToken.StartObject:
                return JToken.Load(reader).ToObject<Dictionary<string, object>>(); 
            default:
                if (reader.ValueType == null && reader.TokenType != Newtonsoft.Json.JsonToken.Null)
                    throw new NotImplementedException("MyObjectConverter");
                return reader.Value;
        }
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotSupportedException("MyObjectConverter");
    }
}

此解决方案的问题是它必须处理其他类型。当reader.TokenType既不是StartArray也不是StartObject而reader.ValueType为null时,它可能会失败。希望有人能提供更好的解决方案。

答案 2 :(得分:0)

我认为你可以用JsonConverter做到这一点。当any字段是JArray时,下面的转换器将JArrays转换为对象列表,并且在所有其他情况下都回退到默认行为。根据您的描述,这正是您正在寻找的。我怀疑代码可以改进,但这应该为您提供解决方案的途径:

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
        JsonSerializer serializer)
    {
        var theFoo = new Foo();

        dynamic dynamicObject = serializer.Deserialize(reader);

        if (dynamicObject.any.GetType() == typeof (JArray))
        {
            var items = new List<object>();

            foreach (var item in dynamicObject.any)
            {
                items.Add(item);
            }

            theFoo.Any = items;
        }
        else
        {
            theFoo.Any = dynamicObject.any.Value;
        }

        return theFoo;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof (Foo);
    }

    public override bool CanRead
    {
        get { return true; }
    }

    public override bool CanWrite
    {
        get { return false; }
    }
}

用法:

var bar = JsonConvert.DeserializeObject<Foo>("{any: ['c', 5]}", new ListJsonConverter());