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

.NET 7 Web API中DateOnly类型解析失败问题求助

问题分析

你遇到的The JSON value could not be converted to DateOnly错误,核心原因是:你传入的startDate/endDate是嵌套对象结构(包含year/month/day等属性),但你使用的DateOnlyTimeOnly.AspNet包默认只支持解析ISO日期字符串格式(比如"2023-05-29"),因此无法识别这种对象格式的日期数据。

解决方案

以下三种方案任选其一即可:

方案一:修改请求负载为ISO日期字符串(最简单)

直接将请求中的日期字段改为标准ISO字符串格式,不需要修改后端代码,包的转换器就能自动解析:

[
  {
    "startDate": "2023-05-29",
    "name": "string",
    "endDate": "2023-11-01"
  }
]

方案二:自定义JSON转换器处理对象格式的DateOnly

如果无法修改请求格式,可编写自定义转换器来解析这种嵌套对象结构的日期:

  1. 创建自定义转换器类:
public class DateOnlyObjectConverter : JsonConverter<DateOnly>
{
    public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType != JsonTokenType.StartObject)
            throw new JsonException("DateOnly字段应为对象格式");

        int year = 0, month = 0, day = 0;

        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndObject) break;
            if (reader.TokenType != JsonTokenType.PropertyName) continue;

            var propName = reader.GetString();
            reader.Read();

            switch (propName.ToLower())
            {
                case "year": year = reader.GetInt32(); break;
                case "month": month = reader.GetInt32(); break;
                case "day": day = reader.GetInt32(); break;
                // dayOfWeek无需处理,DateOnly会自动计算
            }
        }

        return new DateOnly(year, month, day);
    }

    public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        writer.WriteNumber("year", value.Year);
        writer.WriteNumber("month", value.Month);
        writer.WriteNumber("day", value.Day);
        writer.WriteNumber("dayOfWeek", (int)value.DayOfWeek);
        writer.WriteEndObject();
    }
}
  1. 在Program.cs中注册转换器:
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        // 移除包自带的DateOnly转换器(避免冲突)
        var defaultConverter = options.JsonSerializerOptions.Converters
            .FirstOrDefault(c => c is JsonConverter<DateOnly>);
        if (defaultConverter != null)
            options.JsonSerializerOptions.Converters.Remove(defaultConverter);
        
        // 添加自定义转换器
        options.JsonSerializerOptions.Converters.Add(new DateOnlyObjectConverter());
    });

方案三:使用DTO中间对象做数据映射

创建与请求格式匹配的DTO类,接收请求后手动映射为DateOnly类型:

  1. 定义DTO类:
public class DataDto
{
    public DateDto StartDate { get; set; }
    public string Name { get; set; }
    public DateDto EndDate { get; set; }
}

public class DateDto
{
    public int Year { get; set; }
    public int Month { get; set; }
    public int Day { get; set; }
    public int DayOfWeek { get; set; }
}
  1. 修改接口方法:
[HttpPost("Save")]
public async Task<IActionResult> Save([FromBody] IEnumerable<DataDto> dataDtos)
{
    // 将DTO映射为业务实体
    var dataList = dataDtos.Select(dto => new Data
    {
        StartDate = new DateOnly(dto.StartDate.Year, dto.StartDate.Month, dto.StartDate.Day),
        Name = dto.Name,
        EndDate = new DateOnly(dto.EndDate.Year, dto.EndDate.Month, dto.EndDate.Day)
    }).ToList();

    // 业务逻辑处理...

    return Ok();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 11:57:33