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

.NET6 EF6 Razor Pages(非MVC)表单DateOnly字段未填充入库问题

问题根因

.NET 6 原生模型绑定未提供DateOnly/TimeOnly类型的默认绑定逻辑,表单内type="date"输入框提交的yyyy-MM-dd格式字符串无法被自动转换为DateOnly实例,因此日期字段始终被赋值为类型默认值0001-01-01,该值写入PostgreSQL的date类型字段时会被映射为-infinity。该问题出在模型绑定阶段,和EF Core、PostgreSQL数据库本身无关——你调试到ModelState.IsValid判断行时已经拿不到正确日期值,就可以确认这一点。

解决方案

方案1:全局自定义模型绑定器(一劳永逸,推荐)

  1. 新增DateOnly类型专属模型绑定器,适配HTML日期输入框的提交格式:
    using Microsoft.AspNetCore.Mvc.ModelBinding;
    using System.Globalization;
    
    public class DateOnlyModelBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
                throw new ArgumentNullException(nameof(bindingContext));
    
            var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (valueResult == ValueProviderResult.None)
                return Task.CompletedTask;
    
            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueResult);
            var rawValue = valueResult.FirstValue;
    
            if (string.IsNullOrWhiteSpace(rawValue))
                return Task.CompletedTask;
    
            // 优先匹配date输入框默认提交的yyyy-MM-dd格式
            if (DateOnly.TryParseExact(rawValue, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsedDate))
            {
                bindingContext.Result = ModelBindingResult.Success(parsedDate);
                return Task.CompletedTask;
            }
    
            // 兼容其他常见日期格式
            if (DateOnly.TryParse(rawValue, CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate))
            {
                bindingContext.Result = ModelBindingResult.Success(parsedDate);
                return Task.CompletedTask;
            }
    
            bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "日期格式无效");
            return Task.CompletedTask;
        }
    }
    
  2. 新增绑定器提供器,让框架自动识别DateOnly类型并使用上述绑定器:
    using Microsoft.AspNetCore.Mvc.ModelBinding;
    using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
    
    public class DateOnlyModelBinderProvider : IModelBinderProvider
    {
        public IModelBinder? GetBinder(ModelBinderProviderContext context)
        {
            if (context == null)
                throw new ArgumentNullException(nameof(context));
    
            return context.Metadata.ModelType == typeof(DateOnly) 
                ? new BinderTypeModelBinder(typeof(DateOnlyModelBinder)) 
                : null;
        }
    }
    
  3. 在Program.cs中全局注册绑定器,插入到提供器列表最前端优先匹配:
    builder.Services.AddRazorPages(options =>
    {
        options.ModelBinderProviders.Insert(0, new DateOnlyModelBinderProvider());
    });
    
    注册完成后重启项目,所有DateOnly类型的表单字段都会自动完成值绑定,不需要修改现有实体、表单、提交方法代码。

方案2:临时快速修复(无需全局配置)

如果不想新增全局配置,可以直接在Post提交方法中手动从表单取值赋值,绕过默认模型绑定逻辑:

public async Task<IActionResult> OnPost()
{
    // 手动解析绑定两个日期字段
    if (DateOnly.TryParseExact(Request.Form["Todo.CreateDate"], "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var createDate))
    {
        Todo.CreateDate = createDate;
    }
    if (DateOnly.TryParseExact(Request.Form["Todo.DueDate"], "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dueDate))
    {
        Todo.DueDate = dueDate;
    }
    // 清除日期字段的默认绑定错误,避免ModelState校验失败
    ModelState.Remove("Todo.CreateDate");
    ModelState.Remove("Todo.DueDate");

    if (!ModelState.IsValid)
    {
        var errors = ModelState.SelectMany(x => x.Value.Errors.Select(z => z.Exception));
        return Page();
    }

    await _db.Todo.AddAsync(Todo);
    await _db.SaveChangesAsync();
    TempData["success"] = "ToDo created successfully.";
    return RedirectToPage("Index");
}
注意事项
  • 修复后先在OnPost方法入口打断点,确认Todo.CreateDate和Todo.DueDate已经拿到表单提交的正确日期值,再执行数据库写入操作
  • 该问题仅存在于.NET 6版本,.NET 7及以上版本已经内置DateOnly/TimeOnly类型的模型绑定支持,不需要额外处理
  • 如果日期字段为必填项,记得在实体类属性上添加[Required]特性,避免空提交时写入类型默认值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:03:24