C# 目标为抽象对象时的Json.net反序列化问题

C# 目标为抽象对象时的Json.net反序列化问题,c#,json,json.net,deserialization,C#,Json,Json.net,Deserialization,我使用的服务返回一个json 我有一个key-value对象,其中key是一个字符串,value是一个对象,我知道根据该键将对象投射到哪里 它将看起来像: { "key1": "This is key 1", "key2": 12, "key3": ["Key 3 first item", "Key 3 second item"] } 使用简单类型(例如,字符串、长、int等)。没有问题。当我收到一个数组(键3)时,问题就开始了 我的c#代码将如下所示: Dictionary<

我使用的服务返回一个
json

我有一个key-value对象,其中key是一个
字符串
,value是一个
对象
,我知道根据该键将对象投射到哪里

它将看起来像:

{
  "key1": "This is key 1",
  "key2": 12,
  "key3": ["Key 3 first item", "Key 3 second item"]
}
使用简单类型(例如,
字符串
int
等)。没有问题。
当我收到一个
数组
(键3)时,问题就开始了

我的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
Dictionary values=GetValuesFromTheService();
字符串str=(字符串)值[“key1”];//好啊
长lng=(长)值[“键2”];//好啊
列表strs=(列表)值[“key3”];//坏的
键3实际上是一个
JArray
,而不是一个
列表
——我想这是因为我使用
对象
作为一个值,而不是更具体(列表也比
JArray
更好)


对此我能做些什么吗?

如果
key3
JArray
string
值,您可以执行以下操作:

List<string> strs = ((JArray)values["key3"]).Select(t => t.Value<string>()).ToList();
List strs=((JArray)值[“key3”])。选择(t=>t.Value()).ToList();

您应该能够将整个对象解析为一个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");
var j=JObject.Parse(GetValuesFromTheService());
string str=(string)j.SelectToken(“key1”);
long lng=(long)j.SelectToken(“键2”);
var strs=(列表)j.SelectToken(“key3”);

在尝试(反)序列化一些自定义枚举时,我遇到了类似的情况。对于解决方案,我创建了一个自定义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());
JsonConvert.DeserializeObject(req.Content.ReadAsStringAsync().Result,new EnumerationConverter());
很好的一点是,这将变得普遍可用,CustomObjectDto可以将此魔法词典的一个实例作为属性…甚至多个属性…并将仅对根据转换器中的逻辑匹配的属性应用转换…希望这会有所帮助


这里有一个类似主题的链接-->

我知道如何将JArray转换为列表->我希望反序列化能够在幕后以某种方式处理这个问题。你不应该将所有内容反序列化到
字典中。尝试创建一个为JSON建模的C#类,然后使用
JsonConvert.DeserializeObject(jsonString)
()我知道创建抽象字典是一种不好的做法,但我使用的是外部源代码,这就是输出。我无法创建一个支持这种情况的类。它不能编译,也不是我真正想要的。我可以考虑一些可行的解决办法——我正在寻找一种更聪明的方法。