繁体   English   中英

将JSON搜索结果反序列化为强类型列表(JSON.NET)

[英]Deserializing JSON search results into strongly typed lists (JSON.NET)

我有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将不会这样做。 您有以下方法:

  1. 将您的类发布到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 }); 
  2. 创建一个自定义JsonConverter以便在读取JSON时将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

  3. 使用Linq to 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(); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM