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

.NET Core REST API POST请求失败排查及日期时间参数格式规范

解决.NET Core REST API POST请求BadRequest(模型验证失败)问题

你遇到的POST请求返回BadRequest的问题,大概率是因为DateTime和TimeSpan类型的JSON格式不符合.NET Core默认序列化器的要求,同时你的正则表达式也存在潜在问题。下面一步步帮你排查和修复:

1. 核心问题:日期/时间格式不匹配

.NET Core默认使用System.Text.Json进行JSON序列化,对DateTime和TimeSpan有明确的格式要求,如果请求体中的格式不符合,就会触发模型验证失败。

正确的请求格式示例

针对你的Meeting模型,POST请求的JSON体应该遵循以下格式:

{
  "Start_time": "09:00:00",
  "End_time": "10:30:00",
  "Date": "2024-05-20",
  "Url": "https://example.com/team-meeting",
  "Owner": "John Doe",
  "Participant": "Jane Smith"
}
  • Date(DateTime类型,标注[DataType(DataType.Date)]):使用ISO 8601纯日期格式yyyy-MM-dd,比如2024-05-20。也可以接受带时间的格式(如2024-05-20T00:00:00),但DataType.Date注解会让验证更倾向于纯日期。
  • Start_time/End_time(TimeSpan类型,标注[DataType(DataType.Time)]):可以用hh:mm:ss格式(如09:00:00),或者ISO 8601持续时间格式(如PT9H表示9小时,PT1H30M表示1小时30分),前者更直观易读。

2. 优化调试:返回具体的验证错误

当前你的控制器只返回BadRequest(),没有给出具体的验证失败原因,这不利于排查问题。修改Create方法,返回详细的模型错误信息:

[HttpPost]
public IActionResult Create([FromBody] Meeting meet) {
    if (ModelState.IsValid) {
        Guid obj = Guid.NewGuid();
        meet.Id = obj.ToString();
        _dataAccessProvider.AddMeetingRecord(meet);
        return Ok();
    }
    // 返回具体的模型验证错误,方便调试
    return BadRequest(ModelState);
}

这样你就能在响应中看到哪个字段验证失败,比如是Date格式错误,还是Owner的正则不匹配。

3. 修复正则表达式的潜在问题

你的Owner和Participant字段的正则表达式^[(a-zA-Z)' '(a-zA-Z)]*$存在逻辑错误:

  • 这个正则会允许括号(和)、单引号',但你的错误提示是"Characters are not allowed.",显然这不是你想要的。
  • 正确的正则应该只允许字母和空格,修改为:
[RegularExpression(@"^[a-zA-Z ]*$", ErrorMessage = "Only letters and spaces are allowed.")]
public string Owner { get; set; } 

[RegularExpression(@"^[a-zA-Z ]*$", ErrorMessage = "Only letters and spaces are allowed.")]
public string Participant { get; set; }

如果要求字段非空,可以把*改成+(^[a-zA-Z ]+$),同时加上[Required]注解。

4. 自定义日期/时间格式(可选)

如果你需要支持其他格式(比如MM/dd/yyyy),可以在Program.cs(.NET 6+)或Startup.cs(.NET Core 3.x及以前)中配置JSON序列化选项,添加自定义转换器:

.NET 6+ 配置示例

在Program.cs中添加:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        // 自定义DateTime转换器,只接受yyyy-MM-dd格式
        options.JsonSerializerOptions.Converters.Add(new DateTimeOnlyConverter());
        // 自定义TimeSpan转换器,只接受hh:mm:ss格式
        options.JsonSerializerOptions.Converters.Add(new TimeSpanConverter());
    });

// 自定义DateTime转换器
public class DateTimeOnlyConverter : JsonConverter<DateTime>
{
    private readonly string _dateFormat = "yyyy-MM-dd";

    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (DateTime.TryParseExact(reader.GetString(), _dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date))
        {
            return date;
        }
        throw new JsonException($"Invalid date format. Expected {_dateFormat}.");
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString(_dateFormat, CultureInfo.InvariantCulture));
    }
}

// 自定义TimeSpan转换器
public class TimeSpanConverter : JsonConverter<TimeSpan>
{
    private readonly string _timeFormat = "hh:mm:ss";

    public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (TimeSpan.TryParseExact(reader.GetString(), _timeFormat, CultureInfo.InvariantCulture, out TimeSpan time))
        {
            return time;
        }
        throw new JsonException($"Invalid time format. Expected {_timeFormat}.");
    }

    public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString(_timeFormat, CultureInfo.InvariantCulture));
    }
}

这样就能强制要求请求体中的日期和时间使用你指定的格式。

按照以上步骤调整后,你的POST请求应该就能正常通过模型验证了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 11:24:23