JSON.net serializes a json array into a JArray when the destination is an object. How can I change that?

走远了吗. 提交于 2019-12-12 14:20:27

问题


I have a single level json that I want to deserialize into a Dictionary<string,object> using Json.Net.

The dictionary's value can be a primitive, string or a (primitive\string) array.

The deserialization knows how to handle primitives and strings, but when it gets to an array of primitives it deserializes it into a JArray (instead of a primitive array).

Here's a small code example of what I mean:

string jsonStr = @"{""obj"": 7, ""arr"": ['1','2','3']}"; 
Dictionary<string, object> dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonStr);

dict["obj"].GetType(); // long
dict["arr"].GetType(); // JArray. I would like this to be string[].

I'm looking for a way I can interfere in the deserialization process and create a primitive array instead of getting stuck with a JArray.

I've tried doing it with the JsonSerializerSettings, but couldn't nail the spot.


回答1:


Here is a hacky way of doing this. I create a custom JsonConverter class which accepts 2 generic arguments: T1 and T2. T1 gives the type of the array (in this case string) and T2 gives the type of the other object (in this case long). I assume that we basically want a Dictionary, but that part could definitely be improved.

using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string jsonStr = @"{""obj"": 7, ""arr"": ['1','2','3']}";
            Dictionary<string, object> dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonStr, new SpecialConverter<string, long>());

            dict["obj"].GetType(); // long
            dict["arr"].GetType(); // string[].
        }

        class SpecialConverter<T1, T2> : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return true;
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                JToken token = JToken.Load(reader);
                var result = new Dictionary<string, object>();
                if (result.GetType() == objectType)
                {
                    foreach (var item in token)
                    {
                        var prop = (JProperty)item;
                        if (prop.Value.Type == JTokenType.Array)
                        {
                            result.Add(prop.Name, prop.Value.ToObject<T1[]>());
                        }
                        else
                        {
                            result.Add(prop.Name, prop.Value.ToObject<T2>());
                        }
                    }

                    return result;
                }
                else
                {
                    return null;
                }
            }

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

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



回答2:


The reason it does not convert into an array is because you are telling JsonConvert to convert it to an Dictionary<string, object> and that is exactly what its doing based on the fact that it hasn't got a specific Object to convert to , hence its has "guess" picked JArray, If you can have multiple types for the dictionary's value, best thing would be to convert it to dynamic object. This will give you an array if the value of "arr" is array or a string if the value is a simple string.

string jsonStr = @"{""obj"": 7, ""arr"": ['1','2','3']}";
        dynamic dict = JsonConvert.DeserializeObject(jsonStr);
        var arr = dict.arr;
        string firstelement = arr[0]; // print "1"


来源:https://stackoverflow.com/questions/38594282/json-net-serializes-a-json-array-into-a-jarray-when-the-destination-is-an-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!