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

ASP.NET Core 9中Safari浏览器下数据注解日期验证失败问题

解决方案

1. 前端调整:让flatpickr完全接管输入,避免原生日期控件干扰

将TextBoxFor中的type = "date"改为type = "text",防止Safari的原生日期输入行为篡改flatpickr的输出格式:

<div class="col-md-4">
    @Html.LabelWithMandateFor(m => m.WOHeader.EXP_DEL_DATE)
    @Html.TextBoxFor(m => m.WOHeader.EXP_DEL_DATE, "{0:dd-MM-yyyy}", new { @class = "form-control flatpickr flatpickr-input " + woInfo, type = "text", data_provider = "flatpickr" }).DisableIf(() => !Model.FLD_STATUS.REQ_DEL_DATE_OK)
    <span class="invalid-feedback" asp-validation-for="WOHeader.EXP_DEL_DATE"></span>
</div>

同时在页面JS中明确配置flatpickr的输出格式为dd-MM-yyyy:

$('.flatpickr').flatpickr({
    dateFormat: "dd-MM-yyyy",
    // 其他所需配置项
});

2. 确保RequestLocalization中间件正确启用

检查program.cs中是否添加了请求本地化中间件(需放在路由中间件之前),否则自定义文化配置不会生效:

// 配置完RequestLocalizationOptions后添加
app.UseRequestLocalization();

app.UseRouting();
// 其他中间件逻辑

3. 全局/局部配置DateOnly的强制解析规则

如果前端调整后仍存在解析问题,可通过自定义模型绑定器强制按dd-MM-yyyy格式解析日期:

全局绑定器(适用于所有DateOnly字段)

创建自定义绑定器类:

public class DateOnlyModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException(nameof(bindingContext));

        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueProviderResult == ValueProviderResult.None)
            return Task.CompletedTask;

        bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
        var dateStr = valueProviderResult.FirstValue;

        if (string.IsNullOrEmpty(dateStr))
            return Task.CompletedTask;

        if (DateOnly.TryParseExact(dateStr, "dd-MM-yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out var date))
        {
            bindingContext.Result = ModelBindingResult.Success(date);
        }
        else
        {
            bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "无效的日期格式,请使用dd-MM-yyyy");
        }

        return Task.CompletedTask;
    }
}

在program.cs中注册全局绑定器:

builder.Services.AddControllersWithViews(options =>
{
    options.ModelBinderProviders.Insert(0, new BinderTypeModelBinderProvider(typeof(DateOnly), new DateOnlyModelBinder()));
});

局部特性(仅针对当前字段)

直接在EXP_DEL_DATE字段上添加绑定转换器特性:

[BindProperty]
[Required(ErrorMessageResourceType = typeof(MsgsResource), ErrorMessageResourceName = MandatoryFld)]
[JsonPropertyName("expDelDate")]
[Display(Name = nameof(CommonResource.ExpDelDate), ResourceType = typeof(CommonResource))]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
[BindConverter(typeof(DateOnlyConverter), "dd-MM-yyyy")] // 添加此行
public DateOnly EXP_DEL_DATE { get; set; }

对应的转换器类:

public class DateOnlyConverter : IModelBinder
{
    private readonly string _format;

    public DateOnlyConverter(string format)
    {
        _format = format;
    }

    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueProviderResult == ValueProviderResult.None)
            return Task.CompletedTask;

        var dateStr = valueProviderResult.FirstValue;
        if (string.IsNullOrEmpty(dateStr))
            return Task.CompletedTask;

        if (DateOnly.TryParseExact(dateStr, _format, CultureInfo.InvariantCulture, DateTimeStyles.None, out var date))
        {
            bindingContext.Result = ModelBindingResult.Success(date);
        }
        else
        {
            bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, $"无效的日期格式,请使用{_format}");
        }

        return Task.CompletedTask;
    }
}

4. 验证Ajax提交的数据格式

提交表单前可添加简单的格式校验,确保日期值未被篡改:

$('form').submit(function(e) {
    e.preventDefault();
    var expDelDate = $('#WOHeader_EXP_DEL_DATE').val();
    var dateRegex = /^\d{2}-\d{2}-\d{4}$/;
    if (!dateRegex.test(expDelDate)) {
        alert('请输入正确的日期格式(dd-MM-yyyy)');
        return;
    }
    // 执行Ajax提交逻辑
    $.ajax({
        url: $(this).attr('action'),
        method: $(this).attr('method'),
        data: $(this).serialize(),
        success: function(response) {
            // 处理响应
        }
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 19:35:01