我在JSON中有搜索结果,我想将其反序列化为强类型对象
例如:
{
searchresult: {
resultscount: 15,
results: [
{
resultnumber: 1,
values: [
{
key: "bookid",
value: 1424
},
{
key: "name",
value: "C# in depth"
},
]
}
]
}
}
我有这个POCO
public class Book {
public int BookId { get; set; }
public string Name { get; set; }
}
我想要一份书单。是的,我可以为这种情况编写自己的自定义反序列化程序,但我想使用默认的反序列化程序。
有可能做那样的事吗?
IEnumerable<Book> books = JsonConvert.DeserializeObject<IEnumerable<Book>>(json);
Json.NET在没有任何自定义的情况下不会执行此操作。您有以下方法:
-
将您的课程发布到http://json2csharp.com/要创建JSON的文字表示,请使用Linq将结果转换为
Book
类的列表:public class Value { public string key { get; set; } public string value { get; set; } // Type changed from "object" to "string". } public class Result { public int resultnumber { get; set; } public List<Value> values { get; set; } } public class Searchresult { public int resultscount { get; set; } public List<Result> results { get; set; } } public class RootObject { public Searchresult searchresult { get; set; } }
然后
var root = JsonConvert.DeserializeObject<RootObject>(json); var books = root.searchresult.results.Select(result => new Book { Name = result.values.Find(v => v.key == "name").value, BookId = result.values.Find(v => v.key == "bookid").value });
-
创建一个自定义
JsonConverter
,在读取JSON时将其转换为POCO,例如:internal class BookConverter : JsonConverter { public override bool CanWrite { get { return false; } } public override bool CanConvert(Type objectType) { return objectType == typeof(Book); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var values = serializer.Deserialize<List<KeyValuePair<string, string>>>(reader); if (values == null) return existingValue; var book = existingValue as Book; if (book == null) book = new Book(); // The following throws an exception on missing keys. You could handle this differently if you prefer. book.BookId = values.Find(v => v.Key == "bookid").Value; book.Name = values.Find(v => v.Key == "name").Value; return book; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } } public class Result { public int resultnumber { get; set; } [JsonProperty("values")] [JsonConverter(typeof(BookConverter))] public Book Book { get; set; } } public class Searchresult { public int resultscount { get; set; } public List<Result> results { get; set; } } public class RootObject { public Searchresult searchresult { get; set; } }
然后
var root = JsonConvert.DeserializeObject<RootObject>(json); var books = root.searchresult.results.Select(result => result.Book);
在这里,我只实现了
ReadJson
,因为您的问题只询问反序列化。如果需要,可以类似地实现WriteJson
。 -
使用
Linq to JSON
将JSON加载到JObject
的结构化层次结构中,然后使用Linq:将结果转换为Book
的var books = JObject.Parse(json).Descendants() .OfType<JProperty>() .Where(p => p.Name == "values") .Select(p => p.Value.ToObject<List<KeyValuePair<string, string>>>()) .Select(values => new Book { Name = values.Find(v => v.Key == "name").Value, BookId = values.Find(v => v.Key == "bookid").Value }) .ToList();