我有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);
答案 0 :(得分:2)
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
&lt; < / p>
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();