我想将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
我找不到失败的线路,所以也许有人可以在这里帮助我。
谢谢!
您的代码似乎可以完成工作(尽管有更简单的方法可以实现您的目标)。有问题的部分是自我。它以两个阵列组织。
因此,您的代码发布了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.Serialization
中的DataContractJsonSerializer
将使避难所更容易:
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);
}