You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

日份大于12时Newtonsoft.Json反序列化抛出JsonReaderException问题

问题分析

从异常栈可以看出,反序列化时直接调用了JsonReader.ReadDateTimeString而非自定义转换器的ReadJson方法,说明自定义日期转换器未被触发,导致默认的日期解析逻辑尝试将dd/MM/yyyy格式的字符串按美式日期格式(MM/dd/yyyy)解析,当日份大于12时自然失败。

未触发转换器的核心原因有两个:

  • JSON中的属性名startDate与类中的StartDate大小写不匹配,Newtonsoft.Json默认不自动映射驼峰命名,导致属性绑定失败,转换器未生效;
  • JsonReader默认会自动识别日期字符串并尝试解析,跳过了自定义转换器的处理流程。
解决方案

1. 修正属性名映射

给CourseOverview类的StartDate属性添加JsonProperty特性,明确指定JSON中的键名:

public class CourseOverview
{
    [JsonProperty("startDate")]
    [JsonConverter(typeof(CustomDateTimeConverter))]
    public DateTime StartDate { get; set; }
    public string Duration { get; set; }
    public string Title { get; set; }
    public string CourseCode { get; set; }
}

2. 禁用自动日期解析

反序列化时配置JsonSerializerSettings,关闭JsonReader的自动日期识别,确保自定义转换器生效:

public CourseOverview CreateCourseOverview(object obj)
{
    var settings = new JsonSerializerSettings
    {
        DateParseHandling = DateParseHandling.None
        // 若项目全局使用驼峰命名,可添加以下配置替代JsonProperty特性
        // ContractResolver = new CamelCasePropertyNamesContractResolver()
    };
    var courseOverview = JsonConvert.DeserializeObject<CourseOverview>(obj.ToString(), settings);
    Console.WriteLine(courseOverview);
    return courseOverview;
}

3. 修复自定义转换器的空值问题

由于StartDate是值类型DateTime,转换器解析失败时返回null会引发异常,需修改ReadJson方法,解析失败时抛出明确异常或返回默认日期:

public class CustomDateTimeConverter : DateTimeConverterBase
{
    private const string Format = "dd/MM/yyyy";

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteValue(((DateTime)value).ToString(Format));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.Value == null)
        {
            // 若允许日期为空,需将StartDate改为可空类型DateTime?
            throw new ArgumentNullException(nameof(reader.Value), "日期字符串不能为空");
        }

        var s = reader.Value.ToString();
        if (DateTime.TryParseExact(s, Format, CultureInfo.InvariantCulture, DateTimeStyles.None, out var result))
        {
            return result;
        }
        throw new FormatException($"日期格式错误,需符合{Format}格式");
    }
}
验证

修改后,15/10/2020这类符合dd/MM/yyyy格式的字符串会被自定义转换器正确解析,不会再触发默认的日期解析异常。

内容的提问来源于stack exchange,提问作者CRS01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 01:55:31