我目前正在开发.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}
您知道如何解决此问题吗?也许,您知道更好的方法吗?我不想在结果中返回键“数据”,而只是返回一个简单的动态对象列表。
谢谢!
答案 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);`
希望这就是您所需要的。