我正在尝试将一些JSON数据反序列化为应用程序的对象。到目前为止一切都很好,因为JSON数据上的属性是静态的(带有值的键)。现在我得到的结果是密钥是一个动态的数据。
以下是JSON网址示例:
http://en.wikipedia.org/w/api.php?action=query&format=json&pageids=6695&prop=info
生成的JSON是:
{ "query" : { "pages" : { "6695" : { "counter" : "",
"lastrevid" : 468683764,
"length" : 8899,
"ns" : 0,
"pageid" : 6695,
"title" : "Citadel",
"touched" : "2012-01-03T19:16:16Z"
} } } }
好的,这很好,除了我不能将“页面”数据反序列化为一个对象。如果我要为页面定义一个类,它必须如下所示:
public class 6695
{
public string counter { get; set; }
public int lastrevid { get; set; }
public int length { get; set; }
public int ns { get; set; }
public int pageid { get; set; }
public string title { get; set; }
public string touched { get; set; }
}
为了反序列化内容(使用JsonConvert.Deserialize(jsondata)),我们都知道我们不能有一个名为6695的类。不仅如此,类的名称必须是不同的(例如pageid) = 7145必须是7145级。)
如果我使用像JObject.Parse(内容)这样的东西,然后将项目作为JArrays访问,我似乎可以采取一些值,但它非常难看,我仍然坚持试图从页面数组中获取数据。
寻找有人帮助解决这个问题。我不认为这种情况并不常见,它只是我之前遇到过的JSON数据而不确定如何处理它。
谢谢!
PS忘了提到这是在Windows Phone 7上所以“动态”不可用!
答案 0 :(得分:27)
最简单的方法。在这种特殊情况下,可能会去dynamic
。
dynamic data = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
var lastRevId = data.query.pages["6695"].lastrevid;
您可以使用[]
名称引用任何元素,这样您就可以执行data["query"]["pages"]["6695"]["lastrevid"]
之类的操作。这将通过所有那些名称在c#中无效的小对象得到。
答案 1 :(得分:18)
以下是使用https://github.com/facebook-csharp-sdk/simple-json(https://nuget.org/packages/SimpleJson)的方法。
var text = "{\"query\":{\"pages\":{\"6695\":{\"pageid\":6695,\"ns\":0,\"title\":\"Citadel\",\"touched\":\"2012-01-03T19:16:16Z\",\"lastrevid\":468683764,\"counter\":\"\",\"length\":8899}}}}";
(使用动态)
dynamic json = SimpleJson.DeserializeObject(text);
string title = json.query.pages["6695"].title;
foreach (KeyValuePair<string, dynamic> page in json.query.pages)
{
var id = page.Key;
var pageId = page.Value.pageid;
var ns = page.Value.ns;
}
(使用强类型类)
class result
{
public query query { get; set; }
}
class query
{
public IDictionary<string, page> pages { get; set; }
}
class page
{
public long pageid { get; set; }
public string title { get; set; }
}
var result = SimpleJson.DeserializeObject<result>(text);
<强> [更新] 强>
Windows Phone上的,不支持动态,你不想使用强类型的类。
var json = (IDictionary<string, object>)SimpleJson.DeserializeObject(text);
var query = (IDictionary<string, object>)json["query"];
var pages = (IDictionary<string, object>)query["pages"];
var pageKeys = pages.Keys;
var page = (IDictionary<string, object>)pages["6695"];
var title = (string)page["title"];
答案 2 :(得分:2)
我希望下面的例子会有所帮助。 我总是设计一个与json相匹配的模型。当它是您自己的模型设计时,使用该对象要好得多。
从json生成c#模型非常容易。我使用此网站生成模型:http://json2csharp.com
一个完整的例子是:
C#代码:
var targetsObject = Newtonsoft.Json.JsonConvert.DeserializeObject<YourModel>(jsonString);
JSON:
{
"investors": [
{
"name": "06",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": "6.0"
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "07",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": "7.0"
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "08",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": "7.0"
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "09",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "10",
"programs": [
{
"name": "Conventional",
"value": ""
},
{
"name": "FHA - Standard",
"value": ""
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": ""
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": "2.0"
}
]
},
{
"name": "11",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": "6.0"
},
{
"name": "VA IRRRL",
"value": "6.0"
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "12",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": "6.0"
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "13",
"programs": [
{
"name": "Conventional",
"value": ""
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": ""
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": "2.0"
}
]
}
]
}
型号:
public class Program
{
public string name { get; set; }
public string value { get; set; }
}
public class Investor
{
public string name { get; set; }
public List<Program> programs { get; set; }
}
public class RootObject
{
public List<Investor> investors { get; set; }
}
答案 3 :(得分:1)
使用Json.net,您可以这样做:
Dictionary<string,object> result = JsonConvert.DeserializeObject<Dictionary<string,object>>(json);
foreach(var item in result)
Console.WriteLine(item.Key + " " + item.Value);
答案 4 :(得分:0)
如何在JSON字符串中进行简单的搜索和替换?虽然它可能不是最优雅的解决方案,但它可能是最实用的解决方案。
答案 5 :(得分:0)
也许您可以使用一个保留属性来包含对象类型,然后使用本文所示的基本类型:Dynamic types with JSON.NET