Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell JSON.NET to deserialize JArray to a List<object> when object type is provided?

Let's have the following class:

class Foo
{
    public object Any;
}

This class accepts anything in the field Any.

When I call:

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

Any contains System.Int64.

However, when I call:

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

Any contains Newtonsoft.Json.Linq.JArray.

How to configure JSON.NET so that in this case Any would contain List<object>?

CLARIFICATION:

There could be anything, I can call:

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

or

JsonConvert.DeserializeObject<Foo>("{any: ['c', 5]}")

More clarification:

I would like to tell somehow to JSON.NET (maybe using JsonSerializerSettings):

When you encounter object and JSON contains an array, deserialize that to (for instance) List<object>.

like image 452
TN. Avatar asked Jun 29 '15 15:06

TN.


People also ask

How do I deserialize JSON to an object?

NET objects (deserialize) A common way to deserialize JSON is to first create a class with properties and fields that represent one or more of the JSON properties. Then, to deserialize from a string or a file, call the JsonSerializer. Deserialize method.

How do you serialize and deserialize an object in C# using JSON?

It returns JSON data in string format. In Deserialization, it does the opposite of Serialization which means it converts JSON string to custom . Net object. In the following code, it calls the static method DeserializeObject() of the JsonConvert class by passing JSON data.

What is JArray C#?

JArray() Initializes a new instance of the JArray class. JArray(Object) Initializes a new instance of the JArray class with the specified content. JArray(Object[])


2 Answers

Your answer is probably here

Your [5] is an array. All you have to do is to cast it to a list.


You could also create your own converter, like described here

like image 63
Daniel Möller Avatar answered Sep 28 '22 18:09

Daniel Möller


Currently, I have mocked the following solution:

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");
    }
}

Problem of this solution is that it must handle the other types as well. It could fail when reader.TokenType is neither StartArray nor StartObject and reader.ValueType is null. Hopefully someone will provide a better solution.

like image 37
TN. Avatar answered Sep 28 '22 18:09

TN.