当target是一个抽象对象时,Json.net反序列化问题

时间:2015-11-12 14:07:38

标签: c# json json.net deserialization

我使用的服务返回json

我有一个键值对象,其中键是string,值是object,我知道根据键转换对象的位置。

它看起来像:

{
  "key1": "This is key 1",
  "key2": 12,
  "key3": ["Key 3 first item", "Key 3 second item"]
}

使用简单类型(例如)stringslongint等等。没有问题。
当我收到array时我的问题就开始了( KEY3)。

我的c#代码看起来像这样:

Dictionary<string, object> values = GetValuesFromTheService();
string str = (string)values["key1"]; // Ok
long lng = (long)values["key2"]; // Ok
List<string> strs = (List<string>)values["key3"]; // BAD

key3实际上是JArray而不是List<string> - 我想这是因为我使用object作为值并且不是更具体(a {{ 1}}也会比List<object>更好。

我能做些什么吗?

3 个答案:

答案 0 :(得分:1)

您应该能够将整个对象解析为jObject,然后选择返回所需类型的键。这是未经测试但基本的想法。

var j = JObject.Parse(GetValuesFromTheService());
string str = (string)j.SelectToken("key1");
long lng = (long)j.SelectToken("key2");
var strs = (List<string>)j.SelectToken("key3");

答案 1 :(得分:1)

在尝试(de)序列化一些自定义枚举时,我遇到了类似的情况。对于解决方案,我创建了一个自定义的JsonConvertor。这是我用的代码......

public class EnumerationConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var enm = (Enumeration)value;
            writer.WriteValue(enm.Value);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.Value == null)
            {
                return null;
            }

            int value;

            if (reader.ValueType == typeof(Int64))
            {
                value = Convert.ToInt32(reader.Value);
            }
            else
            {
                value = (int)reader.Value;
            }

            return Enumeration.FromValueOrDefault(objectType, value);

        }

        public override bool CanConvert(Type objectType)
        {
            if (objectType.BaseType == null) return false;
            return objectType.BaseType.Name == "Enumeration";
        }
    }

然后,当我想调用它并将json拉回到我的对象中时,这就是那条线...

JsonConvert.DeserializeObject<List<CustomObjectDto>>(req.Content.ReadAsStringAsync().Result, new EnumerationConverter());

好的一点是,它变得普遍可用,而且CustomObjectDto可以将这个魔术字典的实例作为属性...甚至多个......并且仅对根据匹配的属性应用转换转换器中的逻辑...希望有所帮助。

这是一个类似主题的链接 - &gt; http://blog.maskalik.com/asp-net/json-net-implement-custom-serialization/

答案 2 :(得分:0)

如果key3JArray string个值,您可以执行以下操作:

List<string> strs = ((JArray)values["key3"]).Select(t => t.Value<string>()).ToList();