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

ASP.NET Web API接收含DateTimeOffset属性实体的POST请求异常

解决ASP.NET Core API解析带无时区冒号的DateTimeOffset格式问题

问题原因

你遇到的问题是因为ASP.NET Core默认使用的System.Text.Json解析器,对DateTimeOffset类型的时区偏移格式有严格要求——必须带冒号(比如-04:00),而你传入的是-0400这种不带冒号的格式,导致JSON绑定阶段直接解析失败,根本到不了你打算用DateTime.ParseExact()处理的步骤。

解决方案

方案1:自定义JSON转换器(推荐)

写一个自定义的JsonConverter,让它同时支持解析不带冒号的时区格式、带冒号的时区格式,以及无时区的格式。

自定义转换器代码

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

public class CustomDateTimeOffsetConverter : JsonConverter<DateTimeOffset?>
{
    // 定义支持的三种格式
    private const string FormatWithColonOffset = "yyyy-MM-ddTHH:mm:sszzz";
    private const string FormatWithoutColonOffset = "yyyy-MM-ddTHH:mm:sszz";
    private const string FormatWithoutOffset = "yyyy-MM-ddTHH:mm:ss";

    public override DateTimeOffset? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType != JsonTokenType.String)
            return null;

        var dateStr = reader.GetString()!;

        // 依次尝试解析三种格式
        if (DateTimeOffset.TryParseExact(dateStr, FormatWithoutColonOffset, null, System.Globalization.DateTimeStyles.None, out var result))
            return result;
        if (DateTimeOffset.TryParseExact(dateStr, FormatWithColonOffset, null, System.Globalization.DateTimeStyles.None, out result))
            return result;
        if (DateTimeOffset.TryParseExact(dateStr, FormatWithoutOffset, null, System.Globalization.DateTimeStyles.None, out result))
            return result;

        throw new JsonException($"无法解析日期字符串:{dateStr}");
    }

    public override void Write(Utf8JsonWriter writer, DateTimeOffset? value, JsonSerializerOptions options)
    {
        if (value.HasValue)
            writer.WriteStringValue(value.Value.ToString(FormatWithColonOffset));
        else
            writer.WriteNullValue();
    }
}

注册转换器

有两种注册方式,选其中一种即可:

方式A:给单个属性添加标记

在你的Project实体类的LastAnalysisDate属性上,加上转换器标记:

public class Project
{
    public string Key { get; set; }
    public string Name { get; set; }
    
    [JsonConverter(typeof(CustomDateTimeOffsetConverter))]
    public DateTimeOffset? LastAnalysisDate { get; set; }
    // 其他属性...
}
方式B:全局注册(对所有DateTimeOffset?生效)

在Program.cs(或旧版本的Startup.cs)中,配置全局JSON序列化选项:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new CustomDateTimeOffsetConverter());
    });

方案2:修改客户端传入的格式

如果能控制客户端的请求格式,把时区偏移部分加上冒号,比如将"2023-05-31T10:16:08-0400"改成"2023-05-31T10:16:08-04:00",这样默认的解析器就能直接处理,不需要额外代码。

额外说明

错误信息里的"The project field is required.",大概率是模型绑定的其他小问题——比如JSON属性名和模型属性名的大小写匹配问题(不过.NET默认支持大小写不敏感绑定),或者请求的JSON结构和Project类不匹配。解决完日期解析问题后,可以再排查这个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:28:37