.NET对接第三方API:日期数组转DateTimeOffset解析报错求解
.NET 解析第三方API整数数组日期的解决方案
方法1:自定义JSON转换器(推荐)
根据你使用的JSON序列化库,编写自定义转换器处理整数数组到DateTimeOffset的转换:
针对System.Text.Json
创建自定义转换器类:
public class IntArrayToDateTimeOffsetConverter : JsonConverter<DateTimeOffset> { public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartArray) throw new JsonException("Expected array for date value"); var dateParts = new List<int>(); while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) { if (reader.TokenType == JsonTokenType.Number) dateParts.Add(reader.GetInt32()); else throw new JsonException("Invalid date part, expected integer"); } if (dateParts.Count != 3) throw new JsonException("Expected date array with 3 elements: [year, month, day]"); var date = new DateTime(dateParts[0], dateParts[1], dateParts[2]); return new DateTimeOffset(date); } public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) { writer.WriteStartArray(); writer.WriteNumberValue(value.Year); writer.WriteNumberValue(value.Month); writer.WriteNumberValue(value.Day); writer.WriteEndArray(); } }
在DTO字段上添加特性:
public class YourDto { public string Id { get; set; } [JsonConverter(typeof(IntArrayToDateTimeOffsetConverter))] public DateTimeOffset ValidFrom { get; set; } }
或者全局注册转换器:
var options = new JsonSerializerOptions(); options.Converters.Add(new IntArrayToDateTimeOffsetConverter()); var dto = JsonSerializer.Deserialize<YourDto>(jsonString, options);
针对Newtonsoft.Json(Json.NET)
创建自定义转换器:
public class IntArrayToDateTimeOffsetConverter : JsonConverter<DateTimeOffset> { public override DateTimeOffset ReadJson(JsonReader reader, Type objectType, DateTimeOffset existingValue, bool hasExistingValue, JsonSerializer serializer) { var jArray = JArray.Load(reader); if (jArray.Count != 3) throw new JsonException("Expected date array with 3 elements: [year, month, day]"); int year = (int)jArray[0]; int month = (int)jArray[1]; int day = (int)jArray[2]; var date = new DateTime(year, month, day); return new DateTimeOffset(date); } public override void WriteJson(JsonWriter writer, DateTimeOffset value, JsonSerializer serializer) { writer.WriteStartArray(); writer.WriteValue(value.Year); writer.WriteValue(value.Month); writer.WriteValue(value.Day); writer.WriteEndArray(); } }
使用时添加特性:
public class YourDto { public string Id { get; set; } [JsonConverter(typeof(IntArrayToDateTimeOffsetConverter))] public DateTimeOffset ValidFrom { get; set; } }
或者全局注册:
var settings = new JsonSerializerSettings(); settings.Converters.Add(new IntArrayToDateTimeOffsetConverter()); var dto = JsonConvert.DeserializeObject<YourDto>(jsonString, settings);
方法2:修改OpenAPI配置生成兼容类型
调整OpenAPI的validFrom定义,让生成的DTO字段为整数数组,再通过计算属性转换为DateTimeOffset:
修改后的OpenAPI配置:
"validFrom": { "type": "array", "items": { "type": "integer" }, "description": "Date in [year, month, day] format" }
生成的DTO类会包含int[] ValidFrom,手动添加计算属性:
public class YourDto { public string Id { get; set; } public int[] ValidFrom { get; set; } public DateTimeOffset ValidFromDate { get { if (ValidFrom == null || ValidFrom.Length != 3) throw new InvalidOperationException("Invalid date array format"); return new DateTimeOffset(new DateTime(ValidFrom[0], ValidFrom[1], ValidFrom[2])); } } }
方法3:自定义OpenAPI生成模板
如果需要批量处理多个类似字段,可修改OpenAPI生成器的C#模板,让生成的date格式字段自动添加自定义转换器特性,或直接生成兼容的类型转换逻辑。
内容的提问来源于stack exchange,提问作者Khanh Tran
相关产品推荐
相关产品推荐

