JSON反序列化为C#类时多数字段为Null,请求排查问题原因
问题原因与解决方案
核心问题
反序列化后多数字段为Null的问题,主要源于两个关键原因:
- 命名规则不匹配:JSON使用短横线分隔的命名(kebab-case,如
account-number),而C#类属性使用帕斯卡命名(PascalCase,如AccountNumber),Json.NET默认不会自动映射这两种命名格式。 - 数据类型不匹配:JSON中部分字段是数值/布尔类型(如
quantity是整数3、is-suppressed是布尔值false),但你定义的C#类中对应属性是string类型,类型不兼容会导致反序列化失败,字段被设为Null。
修复方案
1. 修正C#类的属性映射与类型
给每个属性添加[JsonProperty]特性指定对应的JSON键名,同时将属性类型修正为与JSON字段匹配的类型:
using Newtonsoft.Json; public class PositionResult { [JsonProperty("account-number")] public string AccountNumber { get; set; } [JsonProperty("symbol")] public string Symbol { get; set; } [JsonProperty("instrument-type")] public string InstrumentType { get; set; } [JsonProperty("underlying-symbol")] public string UnderlyingSymbol { get; set; } [JsonProperty("quantity")] public int Quantity { get; set; } [JsonProperty("quantity-direction")] public string QuantityDirection { get; set; } [JsonProperty("close-price")] public decimal ClosePrice { get; set; } [JsonProperty("average-open-price")] public decimal AverageOpenPrice { get; set; } [JsonProperty("average-yearly-market-close-price")] public decimal AverageYearlyMarketClosePrice { get; set; } [JsonProperty("average-daily-market-close-price")] public decimal AverageDailyMarketClosePrice { get; set; } [JsonProperty("multiplier")] public int Multiplier { get; set; } [JsonProperty("cost-effect")] public string CostEffect { get; set; } [JsonProperty("is-suppressed")] public bool IsSuppressed { get; set; } [JsonProperty("is-frozen")] public bool IsFrozen { get; set; } [JsonProperty("restricted-quantity")] public int RestrictedQuantity { get; set; } [JsonProperty("expires-at")] public DateTime ExpiresAt { get; set; } [JsonProperty("realized-day-gain")] public decimal RealizedDayGain { get; set; } [JsonProperty("realized-day-gain-effect")] public string RealizedDayGainEffect { get; set; } [JsonProperty("realized-day-gain-date")] public DateTime RealizedDayGainDate { get; set; } [JsonProperty("realized-today")] public decimal RealizedToday { get; set; } [JsonProperty("realized-today-effect")] public string RealizedTodayEffect { get; set; } [JsonProperty("realized-today-date")] public DateTime RealizedTodayDate { get; set; } [JsonProperty("created-at")] public DateTime CreatedAt { get; set;} [JsonProperty("updated-at")] public DateTime UpdatedAt { get; set;} public override string ToString() { return this.ReportAllProperties(); } }
2. 保持反序列化代码不变
你的反序列化代码无需修改,只要类的属性映射和类型正确,即可正常解析:
var dataDeSerialized = JsonConvert.DeserializeObject<PositionResult>(jsonParsed, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
补充说明
- 若不想逐个添加
[JsonProperty],也可以自定义命名策略自动处理kebab-case到PascalCase的转换,但逐个指定属性映射更直观且不易出错。 - 将价格、数量等数值类型定义为
decimal而非string,能避免后续类型转换的麻烦,同时更符合金融数据的精度要求。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

