Newtonsoft.Json 反序列化

2 篇文章 0 订阅

1. Newtonsoft.Json With object

Deserialize an Object

账户类

public class Account
{
    public string Email { get; set; }
    public bool Active { get; set; }
    public DateTime CreatedDate { get; set; }
    public IList<string> Roles { get; set; }
}

将字符串转化为账户类,并取Email

string json = @"{
  'Email': 'james@example.com',
  'Active': true,
  'CreatedDate': '2013-01-20T00:00:00Z',
  'Roles': [
    'User',
    'Admin'
  ]
}";

Account account = JsonConvert.DeserializeObject<Account>(json);

Console.WriteLine(account.Email);
// james@example.com


Deserialize a Collection

string json = @"['Starcraft','Halo','Legend of Zelda']";
List<string> videogames = JsonConvert.DeserializeObject<List<string>>(json);

Deserialize a Dictionary

string json = @"{
  'href': '/account/login.aspx',
  'target': '_blank'
}";

Dictionary<string, string> htmlAttributes = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);

Console.WriteLine(htmlAttributes["href"]);
// /account/login.aspx

Console.WriteLine(htmlAttributes["target"]);
// _blank

Deserialize an Anonymous Type

var definition = new { Name = "" };//定义一个匿名类型

string json1 = @"{'Name':'James'}";
var customer1 = JsonConvert.DeserializeAnonymousType(json1, definition);

Console.WriteLine(customer1.Name);
// James

string json2 = @"{'Name':'Mike'}";
var customer2 = JsonConvert.DeserializeAnonymousType(json2, definition);

Console.WriteLine(customer2.Name);
// Mike

Deserialize a DataSet

string json = @"{
  'Table1': [
    {
      'id': 0,
      'item': 'item 0'
    },
    {
      'id': 1,
      'item': 'item 1'
    }
  ]
}";

DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(json);

DataTable dataTable = dataSet.Tables["Table1"];

Console.WriteLine(dataTable.Rows.Count);
// 2

foreach (DataRow row in dataTable.Rows)
{
    Console.WriteLine(row["id"] + " - " + row["item"]);
}
// 0 - item 0
// 1 - item 1

Deserialize with CustomCreationConverter

This sample creates a class that inherits from CustomCreationConverter that instantiates Employee instances for the Person type.

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDate { get; set; }
}

public class Employee : Person
{
    public string Department { get; set; }
    public string JobTitle { get; set; }
}

public class PersonConverter : CustomCreationConverter<Person>
{
    public override Person Create(Type objectType)
    {
        return new Employee();
    }
}

string json = @"{
  'Department': 'Furniture',
  'JobTitle': 'Carpenter',
  'FirstName': 'John',
  'LastName': 'Joinery',
  'BirthDate': '1983-02-02T00:00:00'
}";

Person person = JsonConvert.DeserializeObject<Person>(json, new PersonConverter());

Console.WriteLine(person.GetType().Name);
// Employee

Employee employee = (Employee)person;

Console.WriteLine(employee.JobTitle);
// Carpenter

Deserialize JSON from a file

public class Movie
{
    public string Name { get; set; }
    public int Year { get; set; }
}
Movie movie1 = JsonConvert.DeserializeObject<Movie>(File.ReadAllText(@"c:\movie.json"));

 
using (StreamReader file = File.OpenText(@"c:\movie.json"))
{
    JsonSerializer serializer = new JsonSerializer();
    Movie movie2 = (Movie)serializer.Deserialize(file, typeof(Movie));
}

填充对象(Populate an Object)

public class Account
{
    public string Email { get; set; }
    public bool Active { get; set; }
    public DateTime CreatedDate { get; set; }
    public List<string> Roles { get; set; }
}
Account account = new Account
{
    Email = "james@example.com",
    Active = true,
    CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc),
    Roles = new List<string>
    {
        "User",
        "Admin"
    }
};

string json = @"{
  'Active': false,
  'Roles': [
    'Expired'
  ]
}";

JsonConvert.PopulateObject(json, account);

Console.WriteLine(account.Email);
// james@example.com

Console.WriteLine(account.Active);
// false

Console.WriteLine(string.Join(", ", account.Roles.ToArray()));
// User, Admin, Expired

2. Linq to Json 解析JSON

Linq to JSON 具有从字符串解析JSON或直接从文件加载JSON的方法。

  • 可以从字符串中读取json值
string json = @"{
  CPU: 'Intel',
  Drives: [
    'DVD read/writer',
    '500 gigabyte hard drive'
  ]
}";

JObject o = JObject.Parse(json);
  • 从文本解析JSON数组
string json = @"[
  'Small',
  'Medium',
  'Large'
]";

JArray a = JArray.Parse(json);
  • 从文件中加载JSON
    还可以使用以下方法直接从文件中加载json。ReadFrom(JsonReader).
using (StreamReader reader = File.OpenText(@"c:\person.json"))
{
   JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(reader));
   // do stuff
}

使用LINQ查询JSON

  • 按属性名称或集合索引获取值
string json = @"{
  'channel': {
    'title': 'James Newton-King',
    'link': 'http://james.newtonking.com',
    'description': 'James Newton-King\'s blog.',
    'item': [
      {
        'title': 'Json.NET 1.3 + New license + Now on CodePlex',
        'description': 'Announcing the release of Json.NET 1.3, the MIT license and the source on CodePlex',
        'link': 'http://james.newtonking.com/projects/json-net.aspx',
        'categories': [
          'Json.NET',
          'CodePlex'
        ]
      },
      {
        'title': 'LINQ to JSON beta',
        'description': 'Announcing LINQ to JSON',
        'link': 'http://james.newtonking.com/projects/json-net.aspx',
        'categories': [
          'Json.NET',
          'LINQ'
        ]
      }
    ]
  }
}";

JObject rss = JObject.Parse(json);

string rssTitle = (string)rss["channel"]["title"];
// James Newton-King

string itemTitle = (string)rss["channel"]["item"][0]["title"];
// Json.NET 1.3 + New license + Now on CodePlex

JArray categories = (JArray)rss["channel"]["item"][0]["categories"];
// ["Json.NET", "CodePlex"]

IList<string> categoriesText = categories.Select(c => (string)c).ToList();
// Json.NET
// CodePlex

使用LINQ查询

也可以使用LINQ查询JObject/JArray。 Children()返回JObject/JArray为可计算,然后可以使用标准WHERE/OrderBy/SelectLINQ运算符对其进行查询。

var postTitles =
    from p in rss["channel"]["item"]
    select (string)p["title"];

foreach (var item in postTitles)
{
    Console.WriteLine(item);
}

//LINQ to JSON beta
//Json.NET 1.3 + New license + Now on CodePlex

var categories =
    from c in rss["channel"]["item"].SelectMany(i => i["categories"]).Values<string>()
    group c by c
    into g
    orderby g.Count() descending
    select new { Category = g.Key, Count = g.Count() };

foreach (var c in categories)
{
    Console.WriteLine(c.Category + " - Count: " + c.Count);
}

//Json.NET - Count: 2
//LINQ - Count: 1
//CodePlex - Count: 1
  • Linq To JSON 也可用于手动将JSON转换为.NET对象。
public class Shortie
{
   public string Original { get; set; }
   public string Shortened { get; set; }
   public string Short { get; set; }
   public ShortieException Error { get; set; }
}

public class ShortieException
{
   public int Code { get; set; }
   public string ErrorMessage { get; set; }
}

在使用与.NET对象不太匹配的JSON时,.NET对象之间的手动序列化和反序列化非常有用。

  • 使用LINQ示例反序列化
string jsonText = @"{
  'short': {
    'original': 'http://www.foo.com/',
    'short': 'krehqk',
    'error': {
      'code': 0,
      'msg': 'No action taken'
    }
  }
}";

JObject json = JObject.Parse(jsonText);

Shortie shortie = new Shortie
{
    Original = (string)json["short"]["original"],
    Short = (string)json["short"]["short"],
    Error = new ShortieException
    {
        Code = (int)json["short"]["error"]["code"],
        ErrorMessage = (string)json["short"]["error"]["msg"]
    }
};

Console.WriteLine(shortie.Original);
// http://www.foo.com/

Console.WriteLine(shortie.Error.ErrorMessage);
// No action taken

用SelectToken查询JSON

SelectToken()提供使用单个字符串路径查询LINQ to JSON的方法, JToken.SelectToken 使动态查询变得容易,因为整个查询都是在字符串中定义的。

SelectToken

SelectToken 是 JToken上的一个方法,它接受一个到child token路径。如果在路径的位置找不到token,SelectToken返回子令牌或空引用。
路径由属性名和数组索引组成,数组索引由句点分隔。 如: Manufacturers[0].Name.

  • SelectToken示例
JObject o = JObject.Parse(@"{
  'Stores': [
    'Lambton Quay',
    'Willis Street'
  ],
  'Manufacturers': [
    {
      'Name': 'Acme Co',
      'Products': [
        {
          'Name': 'Anvil',
          'Price': 50
        }
      ]
    },
    {
      'Name': 'Contoso',
      'Products': [
        {
          'Name': 'Elbow Grease',
          'Price': 99.95
        },
        {
          'Name': 'Headlight Fluid',
          'Price': 4
        }
      ]
    }
  ]
}");

string name = (string)o.SelectToken("Manufacturers[0].Name");
// Acme Co

decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price");
// 50

string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name");
// Elbow Grease

SelectToken与JSONPath

JObject o = JObject.Parse(@"{
  'Stores': [
    'Lambton Quay',
    'Willis Street'
  ],
  'Manufacturers': [
    {
      'Name': 'Acme Co',
      'Products': [
        {
          'Name': 'Anvil',
          'Price': 50
        }
      ]
    },
    {
      'Name': 'Contoso',
      'Products': [
        {
          'Name': 'Elbow Grease',
          'Price': 99.95
        },
        {
          'Name': 'Headlight Fluid',
          'Price': 4
        }
      ]
    }
  ]
}");

// manufacturer with the name 'Acme Co'
JToken acme = o.SelectToken("$.Manufacturers[?(@.Name == 'Acme Co')]");

Console.WriteLine(acme);
// { "Name": "Acme Co", Products: [{ "Name": "Anvil", "Price": 50 }] }

// name of all products priced 50 and above
IEnumerable<JToken> pricyProducts = o.SelectTokens("$..Products[?(@.Price >= 50)].Name");

foreach (JToken item in pricyProducts)
{
    Console.WriteLine(item);
}
// Anvil
// Elbow Grease


带有LINQ的SelectToken

** SelectToken可以与标准LINQ方法结合使用。

IList<string> storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList();
// Lambton Quay
// Willis Street

IList<string> firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")).ToList();
// null
// Headlight Fluid

decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price"));
// 149.95

3. JSONPath

使用JSONPath方括号对对象或列阵由前面的路径片段寻址。索引总是从0开始。

JSONPath表达式总是以与XPath表达式结合使用XML文档的方式引用JSON结构。由于JSON结构通常是匿名的,并且不一定有“根成员对象”,所以JSONPath采用抽象名称$分配给外部级别对象。

JSONPath表达式可以使用网点-符号

$.store.book[0].title

或者托架-符号

$[‘store’][‘book’][0][‘title’]

输入路径。内部路径或输出路径将始终转换为更通用的路径。托架-符号。

JSONPath允许通配符成员名称和数组索引的符号*。它借用后人接线员‘.’从…E4X而数组切片语法提案[start🔚step]从…ECMAScript 4.

底层脚本语言的表达式()可以用作显式名称或索引的替代方法,如

$.store.book[(@.length-1)].title

对当前对象使用符号“@”。通过语法支持过滤器表达式。?()如

$.store.book[?(@.price < 10)].title

以下是JSONPath语法元素与其XPath对应项的完整概述和并行比较。

在这里插入图片描述

一个简单的JSON结构开始,该结构基于一个表示书店的XML示例(原始的XML文件).

{ "store": {
    "book": [ 
      { "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      { "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      { "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      { "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}

|XPath	|JSONPath|	结果||---|--|--|/store/book/author|	$.store.book[*].author	|商店里所有书的作者//author|	$..author	|所有作者/store/*	$.store.*	所有的东西都在商店里,有一些书和一辆红色自行车。/store//price	$.store..price	商店里所有东西的价格。//book[3]	$..book[2]	第三本书//book[last()]	$..book[(@.length-1)]$..book[-1:]	最后一本有条不紊的书。//book[position()<3]	$..book[0,1]$..book[:2]	前两本书//book[isbn]	$..book[?(@.isbn)]	过滤所有ISBN编号的书籍//book[price<10]	$..book[?(@.price<10)]	过滤所有低于10的书籍//*	$..*	XML文档中的所有元素。所有JSON结构的成员。|2007-08-22| E4 # JSONPath实现JSONPath是在Javascript中实现的,用于客户端使用,并移植到PHP以供在服务器上使用。

Newtonsoft.Json.Linq 类地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值