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

.Net Core 6中DateTimeOffset无法从HTTP请求绑定到视图模型

.NET Core 6 Web API DateTimeOffset 偏移量丢失问题解决方案

问题分析

你遇到的是DateTimeOffset类型在模型绑定时偏移量未被正确保留的问题。从请求示例来看,传入的是UTC格式时间(2023-05-12T15:52:41.009Z,对应偏移+00:00),若实际需要传入非UTC偏移的时间或绑定后偏移处理不符合预期,可通过以下方案解决:


方案1:配置JSON序列化选项

.NET Core默认使用System.Text.Json,默认解析逻辑虽能处理DateTimeOffset,但显式配置可确保偏移量被严格保留。在Program.cs中添加以下配置:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
        // 添加自定义转换器,强制使用ISO 8601往返格式保留偏移
        options.JsonSerializerOptions.Converters.Add(new DateTimeOffsetConverter());
    });

// 自定义DateTimeOffset转换器
public class DateTimeOffsetConverter : JsonConverter<DateTimeOffset>
{
    public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return DateTimeOffset.TryParse(reader.GetString(), out var result) 
            ? result 
            : DateTimeOffset.UtcNow;
    }

    public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString("o")); // "o"格式严格保留偏移信息
    }
}

方案2:修正Swagger的时间格式支持

如果是Swagger UI自动将带偏移的时间转为UTC(Z结尾),可修改Swagger配置,让其支持自定义偏移的DateTimeOffset输入:

builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Market API", Version = "v1" });
    // 为DateTimeOffset指定Schema格式,提示输入带偏移的ISO 8601时间
    c.MapType<DateTimeOffset>(() => new OpenApiSchema
    {
        Type = "string",
        Format = "date-time-offset",
        Example = new OpenApiString(DateTimeOffset.Now.ToString("o"))
    });
});

配置后Swagger UI会提示输入类似2023-05-12T15:52:41.009+08:00的带偏移格式,而非强制转为UTC。

方案3:检查视图模型字段定义

确保视图模型的StartPeriod字段未被错误特性修饰:

public class SetMarkingInvestmenViewModel
{
    [Required]
    public decimal Investment { get; set; }

    [Required]
    // 避免添加会干扰偏移处理的特性(如[DataType(DataType.DateTime)])
    public DateTimeOffset StartPeriod { get; set; }
}

方案4:调试原始请求内容

若以上方案无效,可在控制器中读取原始请求体,确认是否是前端(Swagger)传入的格式本身丢失了偏移:

[HttpPost("set-investment")]
public IActionResult SetMarketingInvestment([FromBody] SetMarkingInvestmenViewModel model)
{
    // 读取原始请求内容
    Request.Body.Position = 0;
    using var reader = new StreamReader(Request.Body);
    var rawRequestBody = reader.ReadToEnd();
    // 输出到控制台或日志,验证传入的StartPeriod格式
    Console.WriteLine(rawRequestBody);

    // 业务逻辑
    return Ok(model);
}

内容的提问来源于stack exchange,提问作者Antoine a.k.a Zesso Renoux

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:13:16