[英]JSon.Net deserialize custom class
我想將json對象反序列化為自定義類。 該類可能如下所示:
public class CommunicationMessage {
public string Key { get; set; }
public string Value { get; set; }
public List<CommunicationMessage> Childs { get; set; }
}
我想反序列化的json看起來像這樣:
{
"Skills": [{
"Skill": [{
"SkillID": "1",
"ParticipantID": "7",
"CanDo": "True"
}, {
"SkillID": "2",
"ParticipantID": "7",
"CanDo": "True"
}, {
"SkillID": "3",
"ParticipantID": "7",
"CanDo": "False"
}]
}]
}
這是我用來反序列化json的代碼:
private void ReadRecursive(JToken token, ref CommunicationMessage root) {
if (token is JProperty) {
CommunicationMessage msg = new CommunicationMessage();
if (token.First is JValue) {
msg.Key = ((JProperty)token).Name;
msg.Value = (string)((JProperty)token).Value;
} else {
msg.Key = ((JProperty)token).Name;
foreach (JToken child in token.Children()) {
ReadRecursive(child, ref msg);
}
}
root.Childs.Add(msg);
} else {
foreach (JToken child in token.Children()) {
ReadRecursive(child, ref root);
}
}
}
我期望獲得這種等級制度:
Skills
Skill
SkillID:1
ParticipantID:7
CanDo:true
Skill
SkillID:2
ParticipantID:7
CanDo:true
Skill
SkillID:3
ParticipantID:7
CanDo:false
但是我得到這個:
Skills
Skill
SkillID:1
ParticipantID:7
CanDo:
SkillID:2
ParticipantID:7
CanDo:true
SkillID:3
ParticipantID:7
CanDo:false
我找不到失敗的根源,所以也許有人可以在這里幫助我。
謝謝!!
您的代碼似乎可以正常工作(盡管有更簡單的方法可以實現目標)。 有問題的部分是它本身的JSON。 它分為兩個陣列。
因此,您的代碼將輸出Skills
-array(具有一個元素)和Skill
-array,其中將實際包含您期望的3種技能。
{
"Skills": [{ // array -> note the [
"Skill": [{ // array -> note the [
因此,解決此問題的一種方法是編輯JSON(如果可能):
{
"Skills": [{
"SkillID": "1",
"ParticipantID": "7",
"CanDo": "True"
}, {
"SkillID": "2",
"ParticipantID": "7",
"CanDo": "True"
}, {
"SkillID": "3",
"ParticipantID": "7",
"CanDo": "False"
}]
}
output message = JsonConvert.DeserializeObject<CommunicationMessage>(json);
(其中json
是JSON字符串。)
我使用此頁面-json2csharp-創建與您發布的JSON匹配的類:
public class Skill2
{
public string SkillID { get; set; }
public string ParticipantID { get; set; }
public string CanDo { get; set; }
}
public class Skill
{
public List<Skill2> Skill { get; set; }
}
public class CommunicationMessage
{
public List<Skill> Skills { get; set; }
}
類名是自動生成的。 它始終將根對象命名為RootObject
。 但是您可以將其更改為CommunicationMessage
(我做了。)
如果您希望類具有與JSON不匹配的其他屬性名稱,則可以使用屬性來實現。
public class Skill2
{
[JsonProperty["Key"]
public string SkillID { get; set; }
[JsonProperty["Value"]
public string ParticipantID { get; set; }
public string CanDo { get; set; }
}
使用System.Runtime.Serialization
的DataContractJsonSerializer
可以System.Runtime.Serialization
反序列化:
Stream data = File.OpenRead(@"data.json");
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(CommunicationMessage));
CommunicationMessage message = (CommunicationMessage)serializer.ReadObject(data);
但是您還需要一個這樣的類:
[DataContract]
class CommunicationMessage
{
[DataContract]
class SkillsData
{
[DataContract]
internal class SkillData
{
[DataMember(Name = "SkillID")]
internal object SkillID;
[DataMember(Name = "ParticipantID")]
internal object ParticipantID;
[DataMember(Name = "CanDo")]
internal object CanDo;
}
[DataMember(Name = "Skill")]
internal SkillData[] Skill;
}
[DataMember(Name = "Skills")]
SkillsData[] Skills;
}
上面有類SkillData
,其中包含每種技能的數據。 因此,如果采用數組Skill
,則需要通配。
您可以使用遞歸方法中的邏輯來檢查您何時處於正確的級別/對象類型。
void ReadRecursive(JToken token, ref CommunicationMessage root)
{
var p = token as JProperty;
if (p != null && p.Name == "Skill")
{
foreach (JArray child in p.Children())
{
foreach (JObject skill in child.Children())
{
// Create/add a Skill message instance for current Skill (JObject)
var skillMsg = new CommunicationMessage { Key = p.Name };
// Populate Childs for current skill instance
skillMsg.Childs = new List<CommunicationMessage>();
foreach (JProperty skillProp in skill.Children())
{
skillMsg.Childs.Add(new CommunicationMessage
{
Key = skillProp.Name,
Value = (string)skillProp.Value
});
}
root.Childs.Add(skillMsg);
}
}
}
// Recurse
foreach (JToken child in token.Children())
ReadRecursive(child, ref root);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.