如何使用MVC Newtonsoft JSON CustomJsonConverter处理指定格式JSON数据?
用Newtonsoft JSON的CustomJsonConverter处理MongoDB风格日期的JSON
我来帮你搞定这个问题——你的JSON里的日期是MongoDB常用的{"$date": 毫秒级时间戳}格式,默认的Newtonsoft JSON没法直接把它映射到.NET的DateTime类型,所以我们需要写一个自定义转换器来处理这种格式。下面是完整的实现步骤:
1. 定义对应的实体类
首先,我们需要创建和JSON结构匹配的.NET类。你的JSON外层是一个数组,里面的对象包含returnValue数组,所以我们需要两个类:
public class RootObject { [JsonProperty("returnValue")] public List<FacilityRecord> ReturnValue { get; set; } } public class FacilityRecord { [JsonProperty("facility")] public string Facility { get; set; } [JsonProperty("recrd_desc")] public string RecordDescription { get; set; } // 给日期属性指定我们的自定义转换器 [JsonConverter(typeof(UnixMillisecondsDateTimeConverter))] [JsonProperty("update_time")] public DateTime UpdateTime { get; set; } [JsonProperty("control_num")] public int ControlNumber { get; set; } [JsonConverter(typeof(UnixMillisecondsDateTimeConverter))] [JsonProperty("starttime")] public DateTime StartTime { get; set; } [JsonConverter(typeof(UnixMillisecondsDateTimeConverter))] [JsonProperty("endtime")] public DateTime EndTime { get; set; } [JsonProperty("can_exchange_rate")] public int CanExchangeRate { get; set; } }
2. 编写自定义日期转换器
接下来我们实现JsonConverter的子类,专门处理{"$date": 毫秒级时间戳}这种格式:
public class UnixMillisecondsDateTimeConverter : JsonConverter<DateTime> { public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer) { // 读取JSON对象({"$date": 1234567890000}) var jObject = JObject.Load(reader); // 获取$date对应的毫秒数 var timestamp = jObject.Value<long>("$date"); // 从Unix毫秒时间戳转换为DateTime(默认用UTC时间,可根据业务调整) return DateTimeOffset.FromUnixTimeMilliseconds(timestamp).UtcDateTime; } public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer) { // 如果需要把DateTime序列回原格式,这里可以实现 var timestamp = new DateTimeOffset(value).ToUnixTimeMilliseconds(); writer.WriteStartObject(); writer.WritePropertyName("$date"); writer.WriteValue(timestamp); writer.WriteEndObject(); } }
3. 反序列化JSON
现在就可以用这个转换器来处理你的JSON数据了,示例代码如下:
string yourJson = @"[{""returnValue"": [{""facility"":""DRIO"",""recrd_desc"":""DEFAULT"",""update_time"":{""$date"":1509128545000},""control_num"":1,""starttime"":{""$date"":1506830400000},""endtime"":{""$date"":4102462799000},""can_exchange_rate"":2000}, {""facility"":""DRIO"",""recrd_desc"":""TEMP"",""update_time"":{""$date"":1521229607000},""control_num"":37,""starttime"":{""$date"":1513040240000},""endtime"":{""$date"":1544576240000},""can_exchange_rate"":2112}]}]"; // 反序列化外层数组 var rootObjects = JsonConvert.DeserializeObject<List<RootObject>>(yourJson); // 访问第一个returnValue里的第一条记录 var firstRecord = rootObjects[0].ReturnValue[0]; Console.WriteLine($"设施: {firstRecord.Facility}, 更新时间: {firstRecord.UpdateTime}");
额外说明
- 如果不想给每个日期属性加
[JsonConverter]特性,也可以在序列化设置里全局添加转换器:var settings = new JsonSerializerSettings(); settings.Converters.Add(new UnixMillisecondsDateTimeConverter()); var rootObjects = JsonConvert.DeserializeObject<List<RootObject>>(yourJson, settings); - 时间戳转换时默认用了UTC时间,如果你的业务需要本地时间,可以把
UtcDateTime改成LocalDateTime。
内容的提问来源于stack exchange,提问作者SoftwareDveloper
相关产品推荐
相关产品推荐

