C# 使用Json.Net反序列化Json对象

C# 使用Json.Net反序列化Json对象,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我正在尝试用Json.net反序列化一个对象。我能够成功地做到这一点,但这更像是一种黑客行为,因此我正在寻找一种更好/适当的方式来做到这一点 { "page":"admin", "context":"id", "records":{ "rCount":6, "1":[ { "name":"Romeo", "dob":"01\/01\/1970"

我正在尝试用Json.net反序列化一个对象。我能够成功地做到这一点,但这更像是一种黑客行为,因此我正在寻找一种更好/适当的方式来做到这一点

{
"page":"admin",
"context":"id",
"records":{
            "rCount":6,
            "1":[
               {
                  "name":"Romeo",
                  "dob":"01\/01\/1970"
               },
               {
                  "name":"Harry",
                  "dob":"10\/10\/2012"
               },
               {
                  "name":"Lee",
                  "dob":"17\/10\/2012"
               }],
            "2":[
               {
                  "name":"Mark",
                  "dob":"01\/01\/1970"
               },
               {
                  "name":"Jack",
                  "dob":"10\/10\/2012"
               },
               {
                  "name":"Json",
                  "dob":"17\/10\/2012"
               }],

}}
这是与记录对象有关的json字符串。如果它没有rCount变量,则可以将其反序列化为字典,但由于rCount变量,无法将其正确反序列化为字典。该如何正确地对该对象进行反序列化

以下是我的解决方案:

class Program
{
static void Main(string[] args)
{
    var recordFile = JsonConvert.DeserializeObject<RecordFile>(Properties.Resources.data);
}

public class RecordFile
{
    public string Page { get; set; }
    public string Context { get; set; }
    public Records Records { get; set; }
}

public class Records
{
    public int RCount { get; set; }
    [JsonExtensionData]
    private Dictionary<string, object> _reocordList;

    public List<Record[]> RecordList
    {
        get
        {
            if (_reocordList != null && _reocordList.Count > 0)
            {
                return _reocordList.Values.Select(record => JsonConvert.DeserializeObject<Record[]>(record.ToString())).ToList();
            }
            return new List<Record[]>();
        }
    }

}

public class Record
{
    public string Name { get; set; }
    public string Dob { get; set; }
}
}
类程序
{
静态void Main(字符串[]参数)
{
var recordFile=JsonConvert.DeserializeObject(Properties.Resources.data);
}
公共类记录文件
{
公共字符串页{get;set;}
公共字符串上下文{get;set;}
公共记录记录{get;set;}
}
公开课堂记录
{
公共int RCount{get;set;}
[JsonExtensionData]
私人词典记录表;
公共列表记录列表
{
得到
{
如果(_reocrdlist!=null&&u reocrdlist.Count>0)
{
返回_reOrdList.Values.Select(record=>JsonConvert.DeserializeObject(record.ToString()).ToList();
}
返回新列表();
}
}
}
公开课记录
{
公共字符串名称{get;set;}
公共字符串Dob{get;set;}
}
}

我假设您想要完全摆脱
记录
类,结果是这样的:

public class RecordFile
{
    public string Page { get; set; }
    public string Context { get; set; }
    public Dictionary<string, Record[]> Records { get; set; }
}

public class Record
{
    public string Name { get; set; }
    public string Dob { get; set; }
}
现在,当遇到有关属性的错误时,反序列化程序将跳过它。另一种选择是编写一个自定义转换器,但忽略一个属性感觉有些过分


示例:

您可以使用jObject手动解析JSON:

public class RecordFile
{
    public string Page { get; set; }
    public string Context { get; set; }
    public Records Records { get; set; }
}

public class Records
{
    public int RCount { get; set; }
    public IDictionary<string, List<Record>> RecordsDictionary { get; set; } 
}


public class Record
{
    public string Name { get; set; }
    public string Dob { get; set; }
}
公共类记录文件
{
公共字符串页{get;set;}
公共字符串上下文{get;set;}
公共记录记录{get;set;}
}
公开课堂记录
{
公共int RCount{get;set;}
公共IDictionary Records字典{get;set;}
}
公开课记录
{
公共字符串名称{get;set;}
公共字符串Dob{get;set;}
}
然后:

var jObject=jObject.Parse(\*您的json*\);
var recordFile=新记录文件
{
第页=作业对象值(“第页”),
Context=jObject.Value(“Context”),
记录=新记录
{
RCount=jObject[“记录”]。值(“RCount”),
记录词典=
jObject[“记录”].Children()
.Where(prop=>prop.Name!=“rCount”)
.ToDictionary(prop=>prop.Name),
道具=>
prop.Value.ToObject())
}
};

当然,当财产不存在时,处理案件是很容易的。

到目前为止发布的其他答案应该都适用。为了完整起见,我将展示如何使用定制的
JsonConverter
来解决这个问题,并稍微简化您的模型

以下是转换器的代码:

class RecordFileConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(RecordFile));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        RecordFile rf = new RecordFile();
        rf.Page = (string)jo["page"];
        rf.Context = (string)jo["context"];
        JObject records = (JObject)jo["records"];
        rf.RecordCount = (int)records["rCount"];
        rf.Records = records.Properties()
                            .Where(p => p.Name != "rCount")
                            .Select(p => p.Value.ToObject<Record[]>())
                            .ToList();
        return rf;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
然后,按正常方式反序列化:

var recordFile = JsonConvert.DeserializeObject<RecordFile>(json);
var-recordFile=JsonConvert.DeserializeObject(json);

演示

@AndrewWhitaker没有其他方法可以将其去虚拟化。我使用Dictionary是因为JsonExtensionDataAttribute。是的,我在发表我的评论后马上意识到了这一点,哈哈。非常感谢..这很有帮助,没问题;很高兴我能帮忙。
class RecordFileConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(RecordFile));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        RecordFile rf = new RecordFile();
        rf.Page = (string)jo["page"];
        rf.Context = (string)jo["context"];
        JObject records = (JObject)jo["records"];
        rf.RecordCount = (int)records["rCount"];
        rf.Records = records.Properties()
                            .Where(p => p.Name != "rCount")
                            .Select(p => p.Value.ToObject<Record[]>())
                            .ToList();
        return rf;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
[JsonConverter(typeof(RecordFileConverter))]
public class RecordFile
{
    public string Page { get; set; }
    public string Context { get; set; }
    public int RecordCount { get; set; }
    public List<Record[]> Records { get; set; }
}

public class Record
{
    public string Name { get; set; }
    public string Dob { get; set; }
}
var recordFile = JsonConvert.DeserializeObject<RecordFile>(json);