Alpaca Markets API返回JSON无法反序列化及重新序列化问题求解
反序列化失败原因及解决方案
核心问题
接口返回的JSON最外层使用股票代码作为动态键名,没有固定的属性名,常规固定属性的类无法直接匹配结构,这是反序列化失败的核心诱因。
正确类结构定义
首先定义嵌套的子数据类,所有JSON短字段名通过[JsonProperty]特性映射:
// 成交数据结构 public class Trade { [JsonProperty("t")] public DateTime Timestamp { get; set; } [JsonProperty("x")] public string Exchange { get; set; } [JsonProperty("p")] public decimal Price { get; set; } [JsonProperty("s")] public int Size { get; set; } [JsonProperty("c")] public List<string> Conditions { get; set; } [JsonProperty("i")] public long Id { get; set; } [JsonProperty("z")] public string Tape { get; set; } } // 报价数据结构 public class Quote { [JsonProperty("t")] public DateTime Timestamp { get; set; } [JsonProperty("ax")] public string AskExchange { get; set; } [JsonProperty("ap")] public decimal AskPrice { get; set; } [JsonProperty("as")] public int AskSize { get; set; } [JsonProperty("bx")] public string BidExchange { get; set; } [JsonProperty("bp")] public decimal BidPrice { get; set; } [JsonProperty("bs")] public int BidSize { get; set; } [JsonProperty("c")] public List<string> Conditions { get; set; } [JsonProperty("z")] public string Tape { get; set; } } // K线数据结构 public class Bar { [JsonProperty("t")] public DateTime Timestamp { get; set; } [JsonProperty("o")] public decimal Open { get; set; } [JsonProperty("h")] public decimal High { get; set; } [JsonProperty("l")] public decimal Low { get; set; } [JsonProperty("c")] public decimal Close { get; set; } [JsonProperty("v")] public long Volume { get; set; } [JsonProperty("n")] public int TradeCount { get; set; } [JsonProperty("vw")] public decimal VolumeWeightedPrice { get; set; } } // 单标的快照结构 public class Snapshot { [JsonProperty("latestTrade")] public Trade LatestTrade { get; set; } [JsonProperty("latestQuote")] public Quote LatestQuote { get; set; } [JsonProperty("minuteBar")] public Bar MinuteBar { get; set; } [JsonProperty("dailyBar")] public Bar DailyBar { get; set; } [JsonProperty("prevDailyBar")] public Bar PreviousDailyBar { get; set; } }
反序列化代码
Newtonsoft.Json 直接反序列化
最外层直接用Dictionary<string, Snapshot>接收动态股票代码键:
// 配置时间解析规则,适配高精度UTC时间格式 var serializerSettings = new JsonSerializerSettings { DateTimeZoneHandling = DateTimeZoneHandling.Utc, DateParseHandling = DateParseHandling.DateTime }; var snapshots = JsonConvert.DeserializeObject<Dictionary<string, Snapshot>>(jsonContent, serializerSettings);
反序列化后可以直接通过股票代码索引获取对应数据,例如snapshots["AAPL"]即可拿到苹果的快照数据。
Refit 接口适配
Refit接口直接定义返回值为Dictionary<string, Snapshot>即可,无需额外处理:
public interface IAlpacaMarketDataApi { [Get("/v2/stocks/snapshots")] Task<Dictionary<string, Snapshot>> GetSnapshots([Query(CollectionFormat.Multi)] string[] symbols, [Query] string feed = "sip"); }
序列化异常排查
如果反序列化后重新序列化出现异常,检查以下两点:
- 确认类的属性没有循环引用,必要时在序列化设置中开启
ReferenceLoopHandling = ReferenceLoopHandling.Ignore - 确认时间格式配置和反序列化时保持一致,避免时区转换异常
内容的提问来源于stack exchange,提问作者Dag Rasen
相关产品推荐
相关产品推荐

