反序列化对 C# 对象的 Json 响应
Deserializing JsonResponse to a C# Object
我正在尝试使用 JSON 到 C# 转换器反序列化此 JSON 响应。
我以前从来没有遇到过问题,但是对于这个响应,转换的结果很奇怪。
无论如何,这是回应:
{
"get": "standings",
"parameters": {
"league": "520",
"season": "2020"
},
"errors": [],
"results": 1,
"response": [
{
"league": {
"id": 520,
"name": "Acreano",
"country": "Brazil",
"logo": "https://media.api-sports.io/football/leagues/520.png",
"flag": "https://media.api-sports.io/flags/br.svg",
"season": 2020,
"standings": [
[
{
"rank": 1,
"team": {
"id": 1228,
"name": "Galvez",
"logo": "https://media.api-sports.io/football/teams/1228.png"
},
"points": 0,
"goalsDiff": 0,
"group": "Acreano: 2nd Phase",
"form": null,
"status": "same",
"description": "Next Round",
"all": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"home": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"away": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 2,
"team": {
"id": 10478,
"name": "Humaitá",
"logo": "https://media.api-sports.io/football/teams/10478.png"
},
"points": 0,
"goalsDiff": 0,
"group": "Acreano: 2nd Phase",
"form": null,
"status": "same",
"description": "Next Round",
"all": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"home": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"away": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 3,
"team": {
"id": 10854,
"name": "Náuas",
"logo": "https://media.api-sports.io/football/teams/10854.png"
},
"points": 0,
"goalsDiff": 0,
"group": "Acreano: 2nd Phase",
"form": null,
"status": "same",
"description": null,
"all": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"home": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"away": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 4,
"team": {
"id": 6370,
"name": "Vasco da Gama AC",
"logo": "https://media.api-sports.io/football/teams/6370.png"
},
"points": 0,
"goalsDiff": 0,
"group": "Acreano: 2nd Phase",
"form": null,
"status": "same",
"description": null,
"all": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"home": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"away": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"update": "2020-04-24T00:00:00+00:00"
}
],
[
{
"rank": 1,
"team": {
"id": 1228,
"name": "Galvez",
"logo": "https://media.api-sports.io/football/teams/1228.png"
},
"points": 9,
"goalsDiff": 12,
"group": "Acreano: 1st Phase",
"form": "WWW",
"status": "same",
"description": "Next Round",
"all": {
"played": 3,
"win": 3,
"draw": 0,
"lose": 0,
"goals": {
"for": 14,
"against": 2
}
},
"home": {
"played": 1,
"win": 1,
"draw": 0,
"lose": 0,
"goals": {
"for": 2,
"against": 1
}
},
"away": {
"played": 2,
"win": 2,
"draw": 0,
"lose": 0,
"goals": {
"for": 12,
"against": 1
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 2,
"team": {
"id": 10478,
"name": "Humaitá",
"logo": "https://media.api-sports.io/football/teams/10478.png"
},
"points": 6,
"goalsDiff": 0,
"group": "Acreano: 1st Phase",
"form": "WWL",
"status": "up",
"description": "Next Round",
"all": {
"played": 3,
"win": 2,
"draw": 0,
"lose": 1,
"goals": {
"for": 5,
"against": 5
}
},
"home": {
"played": 2,
"win": 1,
"draw": 0,
"lose": 1,
"goals": {
"for": 1,
"against": 4
}
},
"away": {
"played": 1,
"win": 1,
"draw": 0,
"lose": 0,
"goals": {
"for": 4,
"against": 1
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 3,
"team": {
"id": 10854,
"name": "Náuas",
"logo": "https://media.api-sports.io/football/teams/10854.png"
},
"points": 3,
"goalsDiff": 3,
"group": "Acreano: 1st Phase",
"form": "LWL",
"status": "down",
"description": null,
"all": {
"played": 3,
"win": 1,
"draw": 0,
"lose": 2,
"goals": {
"for": 6,
"against": 3
}
},
"home": {
"played": 1,
"win": 1,
"draw": 0,
"lose": 0,
"goals": {
"for": 5,
"against": 0
}
},
"away": {
"played": 2,
"win": 0,
"draw": 0,
"lose": 2,
"goals": {
"for": 1,
"against": 3
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 4,
"team": {
"id": 6370,
"name": "Vasco da Gama AC",
"logo": "https://media.api-sports.io/football/teams/6370.png"
},
"points": 0,
"goalsDiff": -15,
"group": "Acreano: 1st Phase",
"form": "LLL",
"status": "up",
"description": null,
"all": {
"played": 3,
"win": 0,
"draw": 0,
"lose": 3,
"goals": {
"for": 2,
"against": 17
}
},
"home": {
"played": 2,
"win": 0,
"draw": 0,
"lose": 2,
"goals": {
"for": 2,
"against": 12
}
},
"away": {
"played": 1,
"win": 0,
"draw": 0,
"lose": 1,
"goals": {
"for": 0,
"against": 5
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 5,
"team": {
"id": 10853,
"name": "Independência",
"logo": "https://media.api-sports.io/football/teams/10853.png"
},
"points": 0,
"goalsDiff": 0,
"group": "Acreano: 1st Phase",
"form": null,
"status": "down",
"description": null,
"all": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"home": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"away": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"update": "2020-04-24T00:00:00+00:00"
}
]
]
}
}
]
}
这是生成的对象。
public class Parameters
{
public string league { get; set; }
public string season { get; set; }
}
public class League
{
public int id { get; set; }
public string name { get; set; }
public string country { get; set; }
public string logo { get; set; }
public string flag { get; set; }
public int season { get; set; }
public IList<IList<>> standings { get; set; }
}
public class Response
{
public League league { get; set; }
}
public class Example
{
public string get { get; set; }
public Parameters parameters { get; set; }
public IList<object> errors { get; set; }
public int results { get; set; }
public IList<Response> response { get; set; }
}
如你所见,有一个奇怪的publicIList<IList<>> standings { get; set; }
。
我认为它可能取决于常设标签上的双方括号,但我并没有过多地使用 Json 对象。
无论您在做什么 - 它最像是因为在您的 json 中有一个数组数组(列表的列表 w/e)无法处理。
如果我通过 quicktype,我会得到以下对我来说更好的结果;
// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using QuickType;
//
// var myObj = MyObj.FromJson(jsonString);
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class MyObj
{
[JsonProperty("get")]
public string Get { get; set; }
[JsonProperty("parameters")]
public Parameters Parameters { get; set; }
[JsonProperty("errors")]
public List<object> Errors { get; set; }
[JsonProperty("results")]
public long Results { get; set; }
[JsonProperty("response")]
public List<Response> Response { get; set; }
}
public partial class Parameters
{
[JsonProperty("league")]
[JsonConverter(typeof(ParseStringConverter))]
public long League { get; set; }
[JsonProperty("season")]
[JsonConverter(typeof(ParseStringConverter))]
public long Season { get; set; }
}
public partial class Response
{
[JsonProperty("league")]
public League League { get; set; }
}
public partial class League
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("country")]
public string Country { get; set; }
[JsonProperty("logo")]
public Uri Logo { get; set; }
[JsonProperty("flag")]
public Uri Flag { get; set; }
[JsonProperty("season")]
public long Season { get; set; }
[JsonProperty("standings")]
public List<List<Standing>> Standings { get; set; }
}
public partial class Standing
{
[JsonProperty("rank")]
public long Rank { get; set; }
[JsonProperty("team")]
public Team Team { get; set; }
[JsonProperty("points")]
public long Points { get; set; }
[JsonProperty("goalsDiff")]
public long GoalsDiff { get; set; }
[JsonProperty("group")]
public string Group { get; set; }
[JsonProperty("form")]
public string Form { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("all")]
public All All { get; set; }
[JsonProperty("home")]
public All Home { get; set; }
[JsonProperty("away")]
public All Away { get; set; }
[JsonProperty("update")]
public DateTimeOffset Update { get; set; }
}
public partial class All
{
[JsonProperty("played")]
public long Played { get; set; }
[JsonProperty("win")]
public long Win { get; set; }
[JsonProperty("draw")]
public long Draw { get; set; }
[JsonProperty("lose")]
public long Lose { get; set; }
[JsonProperty("goals")]
public Goals Goals { get; set; }
}
public partial class Goals
{
[JsonProperty("for")]
public long For { get; set; }
[JsonProperty("against")]
public long Against { get; set; }
}
public partial class Team
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("logo")]
public Uri Logo { get; set; }
}
public partial class MyObj
{
public static MyObj FromJson(string json) => JsonConvert.DeserializeObject<MyObj>(json, QuickType.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this MyObj self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class ParseStringConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
long l;
if (Int64.TryParse(value, out l))
{
return l;
}
throw new Exception("Cannot unmarshal type long");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (long)untypedValue;
serializer.Serialize(writer, value.ToString());
return;
}
public static readonly ParseStringConverter Singleton = new ParseStringConverter();
}
}
注意这个:
[JsonProperty("standings")]
public List<List<Standing>> Standings { get; set; }
如果你把它扔到一些像https://jsoneditoronline.org
这样的在线编辑器中,你也可以更好地看到它
我正在尝试使用 JSON 到 C# 转换器反序列化此 JSON 响应。 我以前从来没有遇到过问题,但是对于这个响应,转换的结果很奇怪。
无论如何,这是回应:
{
"get": "standings",
"parameters": {
"league": "520",
"season": "2020"
},
"errors": [],
"results": 1,
"response": [
{
"league": {
"id": 520,
"name": "Acreano",
"country": "Brazil",
"logo": "https://media.api-sports.io/football/leagues/520.png",
"flag": "https://media.api-sports.io/flags/br.svg",
"season": 2020,
"standings": [
[
{
"rank": 1,
"team": {
"id": 1228,
"name": "Galvez",
"logo": "https://media.api-sports.io/football/teams/1228.png"
},
"points": 0,
"goalsDiff": 0,
"group": "Acreano: 2nd Phase",
"form": null,
"status": "same",
"description": "Next Round",
"all": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"home": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"away": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 2,
"team": {
"id": 10478,
"name": "Humaitá",
"logo": "https://media.api-sports.io/football/teams/10478.png"
},
"points": 0,
"goalsDiff": 0,
"group": "Acreano: 2nd Phase",
"form": null,
"status": "same",
"description": "Next Round",
"all": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"home": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"away": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 3,
"team": {
"id": 10854,
"name": "Náuas",
"logo": "https://media.api-sports.io/football/teams/10854.png"
},
"points": 0,
"goalsDiff": 0,
"group": "Acreano: 2nd Phase",
"form": null,
"status": "same",
"description": null,
"all": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"home": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"away": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 4,
"team": {
"id": 6370,
"name": "Vasco da Gama AC",
"logo": "https://media.api-sports.io/football/teams/6370.png"
},
"points": 0,
"goalsDiff": 0,
"group": "Acreano: 2nd Phase",
"form": null,
"status": "same",
"description": null,
"all": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"home": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"away": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"update": "2020-04-24T00:00:00+00:00"
}
],
[
{
"rank": 1,
"team": {
"id": 1228,
"name": "Galvez",
"logo": "https://media.api-sports.io/football/teams/1228.png"
},
"points": 9,
"goalsDiff": 12,
"group": "Acreano: 1st Phase",
"form": "WWW",
"status": "same",
"description": "Next Round",
"all": {
"played": 3,
"win": 3,
"draw": 0,
"lose": 0,
"goals": {
"for": 14,
"against": 2
}
},
"home": {
"played": 1,
"win": 1,
"draw": 0,
"lose": 0,
"goals": {
"for": 2,
"against": 1
}
},
"away": {
"played": 2,
"win": 2,
"draw": 0,
"lose": 0,
"goals": {
"for": 12,
"against": 1
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 2,
"team": {
"id": 10478,
"name": "Humaitá",
"logo": "https://media.api-sports.io/football/teams/10478.png"
},
"points": 6,
"goalsDiff": 0,
"group": "Acreano: 1st Phase",
"form": "WWL",
"status": "up",
"description": "Next Round",
"all": {
"played": 3,
"win": 2,
"draw": 0,
"lose": 1,
"goals": {
"for": 5,
"against": 5
}
},
"home": {
"played": 2,
"win": 1,
"draw": 0,
"lose": 1,
"goals": {
"for": 1,
"against": 4
}
},
"away": {
"played": 1,
"win": 1,
"draw": 0,
"lose": 0,
"goals": {
"for": 4,
"against": 1
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 3,
"team": {
"id": 10854,
"name": "Náuas",
"logo": "https://media.api-sports.io/football/teams/10854.png"
},
"points": 3,
"goalsDiff": 3,
"group": "Acreano: 1st Phase",
"form": "LWL",
"status": "down",
"description": null,
"all": {
"played": 3,
"win": 1,
"draw": 0,
"lose": 2,
"goals": {
"for": 6,
"against": 3
}
},
"home": {
"played": 1,
"win": 1,
"draw": 0,
"lose": 0,
"goals": {
"for": 5,
"against": 0
}
},
"away": {
"played": 2,
"win": 0,
"draw": 0,
"lose": 2,
"goals": {
"for": 1,
"against": 3
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 4,
"team": {
"id": 6370,
"name": "Vasco da Gama AC",
"logo": "https://media.api-sports.io/football/teams/6370.png"
},
"points": 0,
"goalsDiff": -15,
"group": "Acreano: 1st Phase",
"form": "LLL",
"status": "up",
"description": null,
"all": {
"played": 3,
"win": 0,
"draw": 0,
"lose": 3,
"goals": {
"for": 2,
"against": 17
}
},
"home": {
"played": 2,
"win": 0,
"draw": 0,
"lose": 2,
"goals": {
"for": 2,
"against": 12
}
},
"away": {
"played": 1,
"win": 0,
"draw": 0,
"lose": 1,
"goals": {
"for": 0,
"against": 5
}
},
"update": "2020-04-24T00:00:00+00:00"
},
{
"rank": 5,
"team": {
"id": 10853,
"name": "Independência",
"logo": "https://media.api-sports.io/football/teams/10853.png"
},
"points": 0,
"goalsDiff": 0,
"group": "Acreano: 1st Phase",
"form": null,
"status": "down",
"description": null,
"all": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"home": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"away": {
"played": 0,
"win": 0,
"draw": 0,
"lose": 0,
"goals": {
"for": 0,
"against": 0
}
},
"update": "2020-04-24T00:00:00+00:00"
}
]
]
}
}
]
}
这是生成的对象。
public class Parameters
{
public string league { get; set; }
public string season { get; set; }
}
public class League
{
public int id { get; set; }
public string name { get; set; }
public string country { get; set; }
public string logo { get; set; }
public string flag { get; set; }
public int season { get; set; }
public IList<IList<>> standings { get; set; }
}
public class Response
{
public League league { get; set; }
}
public class Example
{
public string get { get; set; }
public Parameters parameters { get; set; }
public IList<object> errors { get; set; }
public int results { get; set; }
public IList<Response> response { get; set; }
}
如你所见,有一个奇怪的publicIList<IList<>> standings { get; set; }
。
我认为它可能取决于常设标签上的双方括号,但我并没有过多地使用 Json 对象。
无论您在做什么 - 它最像是因为在您的 json 中有一个数组数组(列表的列表 w/e)无法处理。
如果我通过 quicktype,我会得到以下对我来说更好的结果;
// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using QuickType;
//
// var myObj = MyObj.FromJson(jsonString);
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class MyObj
{
[JsonProperty("get")]
public string Get { get; set; }
[JsonProperty("parameters")]
public Parameters Parameters { get; set; }
[JsonProperty("errors")]
public List<object> Errors { get; set; }
[JsonProperty("results")]
public long Results { get; set; }
[JsonProperty("response")]
public List<Response> Response { get; set; }
}
public partial class Parameters
{
[JsonProperty("league")]
[JsonConverter(typeof(ParseStringConverter))]
public long League { get; set; }
[JsonProperty("season")]
[JsonConverter(typeof(ParseStringConverter))]
public long Season { get; set; }
}
public partial class Response
{
[JsonProperty("league")]
public League League { get; set; }
}
public partial class League
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("country")]
public string Country { get; set; }
[JsonProperty("logo")]
public Uri Logo { get; set; }
[JsonProperty("flag")]
public Uri Flag { get; set; }
[JsonProperty("season")]
public long Season { get; set; }
[JsonProperty("standings")]
public List<List<Standing>> Standings { get; set; }
}
public partial class Standing
{
[JsonProperty("rank")]
public long Rank { get; set; }
[JsonProperty("team")]
public Team Team { get; set; }
[JsonProperty("points")]
public long Points { get; set; }
[JsonProperty("goalsDiff")]
public long GoalsDiff { get; set; }
[JsonProperty("group")]
public string Group { get; set; }
[JsonProperty("form")]
public string Form { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("all")]
public All All { get; set; }
[JsonProperty("home")]
public All Home { get; set; }
[JsonProperty("away")]
public All Away { get; set; }
[JsonProperty("update")]
public DateTimeOffset Update { get; set; }
}
public partial class All
{
[JsonProperty("played")]
public long Played { get; set; }
[JsonProperty("win")]
public long Win { get; set; }
[JsonProperty("draw")]
public long Draw { get; set; }
[JsonProperty("lose")]
public long Lose { get; set; }
[JsonProperty("goals")]
public Goals Goals { get; set; }
}
public partial class Goals
{
[JsonProperty("for")]
public long For { get; set; }
[JsonProperty("against")]
public long Against { get; set; }
}
public partial class Team
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("logo")]
public Uri Logo { get; set; }
}
public partial class MyObj
{
public static MyObj FromJson(string json) => JsonConvert.DeserializeObject<MyObj>(json, QuickType.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this MyObj self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class ParseStringConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
long l;
if (Int64.TryParse(value, out l))
{
return l;
}
throw new Exception("Cannot unmarshal type long");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (long)untypedValue;
serializer.Serialize(writer, value.ToString());
return;
}
public static readonly ParseStringConverter Singleton = new ParseStringConverter();
}
}
注意这个:
[JsonProperty("standings")]
public List<List<Standing>> Standings { get; set; }
如果你把它扔到一些像https://jsoneditoronline.org
这样的在线编辑器中,你也可以更好地看到它