c# - 通过结合 UnixDateTimeConverter 和 ContractResolver 反序列化嵌套项
问题描述
鉴于以下 JSON,我想用 Newtonsoft.Json 反序列化:
{
"ticker": "AAPL",
"status": "OK",
"adjusted": true,
"queryCount": 55,
"resultsCount": 2,
"results": [
{
"T": "AAPL",
"v": 31315282,
"o": 102.87,
"c": 103.74,
"h": 103.82,
"l": 102.65,
"t": 1549314000000,
"n": 4
},
{
"T": "AAPL",
"v": 11315282,
"o": 102.13,
"c": 103.44,
"h": 104.12,
"l": 102.33,
"t": 1549315000000,
"n": 4
}
]
}
我已经创建了可以反序列化的类:
public class Response
{
public string Ticker { get; set; }
public string Status { get; set; }
public bool Adjusted { get; set; }
public int QueryCount { get; set; }
public int ResultsCount { get; set; }
[JsonProperty("results")]
public List<OpenHighLowClose> OpenHighLowCloseList { get; set; }
}
而且我有以下DTO,它在我的代码中使用(但我不想在这个类上放置属性):
public class OpenHighLowClose
{
public OpenHighLowClose(DateTime dateTime, decimal open, decimal high, decimal low, decimal close, decimal volume)
{
DateTime = dateTime;
Open = open;
High = high;
Low = low;
Close = close;
Volume = volume;
}
public DateTime DateTime { get; private set; }
public Decimal Open { get; private set; }
public Decimal High { get; private set; }
public Decimal Low { get; private set; }
public Decimal Close { get; private set; }
public Decimal Volume { get; private set; }
}
我需要通过构造函数进行映射(我相信解串器默认会这样做),所以对于 OpenHighLowClose 我可以写如下:
public class OpenHighLowCloseContractResolver : DefaultContractResolver
{
private Dictionary<string, string> PropertyMappings { get; set; }
public CustomContractResolver()
{
this.PropertyMappings = new Dictionary<string, string>
{
{"t", "DateTime"},
{"o", "Open"},
{"h", "High"},
{"l", "Low"},
{"c", "Close"},
{"v", "Volume"},
};
}
protected override string ResolvePropertyName(string propertyName)
{
string resolvedName = null;
var resolved = this.PropertyMappings.TryGetValue(propertyName, out resolvedName);
return (resolved) ? resolvedName : base.ResolvePropertyName(propertyName);
}
}
我将如何组合上面的代码,以便我可以Response
使用构造函数和时间戳转换进行反序列化。
我已经看到JsonConverter
,JsonConstructor
和对时间转换CustomContractResolver
进行[JsonConverter(typeof(UnixDateTimeConverter))]
排序,但我对如何组合所有这些类感到困惑。
解决方案
我使用JsonConverter
.
这最终并没有那么糟糕,如果最佳实践与否,请对评论感兴趣:
public class AggregateResponse
{
public string Ticker { get; set; }
public string Status { get; set; }
public bool Adjusted { get; set; }
public int QueryCount { get; set; }
public int ResultsCount { get; set; }
public List<OpenHighLowClose> Results { get; set; }
}
public class OpenHighLowCloseConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject obj = JObject.Load(reader);
var timestamp = DateTimeOffset
.FromUnixTimeMilliseconds((long)obj["t"])
.UtcDateTime;
return new OpenHighLowClose(
timestamp,
(decimal)obj["o"],
(decimal)obj["h"],
(decimal)obj["l"],
(decimal)obj["c"],
(int)obj["v"]);
}
public override bool CanConvert(Type objectType)
=> objectType == typeof(OpenHighLowClose);
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
=> throw new NotImplementedException();
}
我用以下反序列化:
var settings = new JsonSerializerSettings
{
Converters = new List<JsonConverter> { new OpenHighLowCloseConverter() }
};
var deserialized = JsonConvert.DeserializeObject<AggregateResponse>(result, settings);
推荐阅读
- python - 这是我的第一个 python 项目,我一直试图在屏幕上向下移动一个简单的矩形,因为俄罗斯方块块掉下来但失败了
- laravel - 如何获取集合关系中的总项目
- google-apps-script - 将 html 文件中的所有表格数据抓取到 Google 工作表中
- html - shopify 中的样式部分
- python - 通过 Kinesis firehose 将流数据传输到 S3 的代码在调用 PutRecord 操作时不断产生错误:(UnknownOperationException)
- blockchain - 了解区块链智能合约
- reactjs - 在其他页面 React 的 URL 中显示数据感谢 id
- html - 为什么位置:固定;不适用于 justify-content: space-between;?
- google-chrome-extension - manifest v3 Chrome 扩展中的 web_accessible_resources
- python - TypeError:参数不匹配任何重载调用:QCompleter(父:QObject = None):参数太多QCompleter(QAbstractItemMode)修复?