簡體   English   中英

JSon.Net反序列化自定義類

[英]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"
    }]
}

使用Newtonsoft Json.NET

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.SerializationDataContractJsonSerializer可以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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM