将Json转换为List <expandoobject>

时间:2018-10-18 08:00:57

标签: c# asp.net json expandoobject

我目前正在开发.NET Framework 4.7.2应用程序。我正在从Web API检索数据作为JSON字符串结果,我需要将结果转换为ExpandoObject的IEnumerable或IList。

我的JSON可以具有动态属性,如下所示:

{ "data" : [
   {"Id":1, Text:"Test1", coolProp: 213 },
   {"Id":2, Text:"Test2"},
   {"Id":3, Text:"Test3", otherProp: "cool" },
]}

我需要选择不带键“ data”的JSON对象,并返回ExpandoObjects的动态列表。

我当前的C#看起来像这样:

var json = JsonConvert.DeserializeObject<ExpandoObject>(await response.Content.ReadAsStringAsync());
var result = json.FirstOrDefault(x => x.Key == "data").Value;

这很好用,但是结果只是一个包含多个ExpandoObjects的简单对象。

我不能将结果隐式或显式地转换为List<ExpandoObject>

当我尝试返回结果时,错误消息如下:

无法将类型'object'隐式转换为List。

当我尝试显式投射时,结果为null:

var result= json.FirstOrDefault(x => x.Key == "data").Value as List<IDictionary<int, ExpandoObject>>;

不进行强制转换的结果在立即窗口中看起来像这样:

result
Count = 7
    [0]: {System.Dynamic.ExpandoObject}
    [1]: {System.Dynamic.ExpandoObject}
    [2]: {System.Dynamic.ExpandoObject}
    [3]: {System.Dynamic.ExpandoObject}
    [4]: {System.Dynamic.ExpandoObject}
    [5]: {System.Dynamic.ExpandoObject}
    [6]: {System.Dynamic.ExpandoObject}

您知道如何解决此问题吗?也许,您知道更好的方法吗?我不想在结果中返回键“数据”,而只是返回一个简单的动态对象列表。

谢谢!

2 个答案:

答案 0 :(得分:3)

您可以尝试解析json并准确提取所需的内容。 我假设您要在根元素内定位data,而不是data本身。

所以您继续

JObject.Parse(myJson)["data"]

此外,如果您希望结果成为列表,则将其反序列化为List<ExpandObject>而不是ExpandObject

这是可以在本地测试的完全正常的演示-

 internal class ExpandObject
    {
        public int Id { get; set; }
        public string Text { get; set; }
        public string coolProp { get; set; }
        public string otherProp { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            String text = "{\"data\":[{\"Id\":1,\"Text\":\"Test1\",\"coolProp\":213},{\"Id\":2,\"Text\":\"Test2\"},{\"Id\":3,\"Text\":\"Test3\",\"otherProp\":\"cool\"}]}";
            var deserialized = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ExpandObject>>(Convert.ToString(JObject.Parse(text)["data"]));
            Console.ReadLine();
        }
    }

答案 1 :(得分:1)

我想我找到了您的问题的解决方案。我遇到的问题是,一旦获得第一个键,它将把它解释为一个对象,而不是一个expandoObject。但是,由于您需要字典,因此可以将其强制转换为键的字典功能。

var json = JsonConvert.DeserializeObject<ExpandoObject>(jsonData);
var result = json.FirstOrDefault(x => x.Key == "data").Value;
var items = ((IEnumerable<Object>)json.FirstOrDefault(x => x.Key == "data").Value).ToDictionary(x => ((ExpandoObject)x).FirstOrDefault(y=>y.Key == "Id").Value, x=>x);`

如果您需要将生成的字典作为Dictionary,则可以为此替换最后一行:

Dictionary<int, ExpandoObject> items = ((IEnumerable<Object>)json.FirstOrDefault(x => x.Key == "data").Value).ToDictionary(x => int.Parse(((ExpandoObject)x).FirstOrDefault(y=>y.Key == "Id").Value.ToString()), x=>(ExpandoObject)x);`

希望这就是您所需要的。