MVC Core 和 EF Core 手动解析输入文本框中的日期时间

MVC Core and EF Core manually parse date time in input text box

我有一个带有 EF 核心数据上下文的 MVC 核心项目。我使用脚手架来创建 CRUD。我只想知道当用户点击保存时,是否可以使用我的自定义逻辑来解析文本框中的日期时间?

目前我在创建页面中有这个:

<div class="form-group col-md-6 col-xs-12">
    <label asp-for="Lead.BDayDateTime" class="control-label"></label>
    <input asp-for="Lead.BDayDateTime" class="form-control" />
    <span asp-validation-for="Lead.BDayDateTime" class="text-danger"></span>
</div>

及其在我的模型中的定义:

[Required(ErrorMessage = "Please enter year of birth or birthday (ex. 1363, 1984, 1984-09-23, 1363-07-01)")]
[Display(Name = "Birthday", Prompt = "Birth Year or Birthday", Description = "Please enter year of birth or birthday (ex. 1363, 1984, 1984-09-23, 1363-07-01)")]
[DisplayFormat(NullDisplayText = "Not Entered", DataFormatString = "{0:yyyy}", ApplyFormatInEditMode = true)]
public DateTime BDayDateTime { get; set; }

我想手动解析日期时间,以便用户可以输入非公历日期时间值(我会在保存到数据库之前将它们转换为公历)。

如果您想定义自定义验证逻辑,您需要创建一个派生自 ValidationAttribute

的自定义 class

示例代码:

using System.ComponentModel.DataAnnotations;

namespace StatisticsWeb.Models
{
    public class PatientFormBirthdayValidation : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var patient = (Patient)validationContext.ObjectInstance;
            if (patient.BirthDate == null)
            {
                return new ValidationResult("Date of Birth field is required");
            }
            else if ((patient.BirthDate >= DateTime.Now) || (patient.BirthDate < DateTime.MinValue))
            {
                return new ValidationResult("Date of Birth is invalid");
            }
            else
            {
                return ValidationResult.Success;
            }
        }
    }
}

并用这个属性装饰你的模型:

[PatientFormBirthdayValidation]
public DateTime BDayDateTime { get; set; }

当然你可以使用其他属性,比如[Display(Name = "Date of Birth")][Required]

我找到了使用 TypeConverter:

将我的自定义日期字符串解析为 DateTime 的解决方案

我创建了一个自定义类型转换器:

public class JalaliAwareDateConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context,
        Type sourceType)
    {
        if (sourceType == typeof(string))
            return true;
        return base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string s)
        {
            return s.ParseDateString(); // My custom parser
        }

        return base.ConvertFrom(context, culture, value);
    }
}

并在 Startup.cs 中注册(根据我的经验并感谢 this answer 和@zdeněk 评论,TypeConverter 属性在 asp.net 核心中不起作用):

TypeDescriptor.AddAttributes(typeof(DateTime), new TypeConverterAttribute(typeof(JalaliAwareDateConverter)));

现在,我在 DateTime 属性 中有有效值,但验证仍然失败。 这个问题是因为正则表达式验证器试图验证 DateTime 对象!删除了正则表达式验证器,瞧,它起作用了!