C# JToken.Parse与json对象中的日期处理踩坑记录

发布时间 2023-04-12 10:36:24作者: C余L小R鱼

json可以转换为JObject 并通过SelectToken来获取这个对象中的某个属性 某个节点

  1. 将json解析为JObject
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
        }
      ]
    }
  ]
}");

2.直接通过属性名获取对应值

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

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

2.也可通过jsonPat获取对应值

// 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);
}

2.也可以通过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"));

但是通过SelectToken获取时间类型的对应值时 会存在默认转换 无法指定时区

比如:我有一个特定的日期格式(MicrosoftDateFormat) 序列化后日期表现为

"DocumentModifiedDate": "/Date(1533686400000)/"

但当使用Jobject.SelectToken后 日期被默认转换为

"DocumentModifiedDate": "2018-08-08T00:00:00Z"

与真正对应的时间差了8小时