【问题标题】:RequiredAttribute for DateTime if field empty or wrong如果字段为空或错误,则 DateTime 的RequiredAttribute
【发布时间】:2018-11-20 04:08:35
【问题描述】:

RequiredAttribute 适用于 string,但不适用于 DateTime。例如:

    [Required]
    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public string Name { get; set; }

    [Required]
    [DataType(DataType.DateTime)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd-MMM-yyyy}", ConvertEmptyStringToNull = false)]
    public DateTime Birthdate { get; set; }

如果Name 为空,则验证会显示错误,但如果Birthdate 为空,则不会发生任何事情。我看了看:

ASP MVC 5 Client Validation for Range of Datetimes

MVC Model Range Validator?

但仍然不适用于DateTime

【问题讨论】:

  • [Required] 属性确实适用于 DateTime,如果您清除文本框中的值,则假设您的视图正确,将显示一条验证消息。

标签: c# asp.net-mvc-4


【解决方案1】:

DateTime是结构体,结构体是“值类型”,不是“引用类型”,所以它们的默认值不是null,对于DateTime1/1/0001 12:00:00 AMint有它的默认值作为0

string 类型是“引用类型”,所有引用类型的默认值为null

因此,如果您想检查值类型是否为 null,您应该将其创建为 Nullable

像这样:

public DateTime? Birthdate { get; set; }

或者

public Nullable<DateTime> Birthdate { get; set; }

【讨论】:

    【解决方案2】:

    我认为 DateTime 有一个标准值,所以你应该添加一个范围属性而不是 required

    [Range(typeof(DateTime), "01/01/1900", "01/01/2100", ErrorMessage="Date is out of Range")]
    

    这样的事情应该可以解决问题

    【讨论】:

      【解决方案3】:

      如果您不想使 DateTime 可以为空,但仍将默认值 0001-01-01 12:00:00 AM (DateTime.MinValue) 解释为“缺失”,只需创建自己的验证器:

      public class RequiredDateTimeAttribute : ValidationAttribute
      {
          public RequiredDateTimeAttribute()
          {
              ErrorMessage = "The {0} field is required";
          }
      
          public override bool IsValid(object value)
          {
              if (!(value is DateTime))
                  throw new ArgumentException("value must be a DateTime object");
      
              if ((DateTime)value == DateTime.MinValue)
                  return false;
      
              return true;
          }
      
          public override string FormatErrorMessage(string name)
          {
              return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name);
          }
      }
      

      【讨论】:

      • @NET7 贡献者
      【解决方案4】:

      这是因为Birthdate属性不可为空,所以它总是会有一个值,如果改为:

      public Nullable<DateTime> Birthdate { get; set; }
      

      那么所需的属性将按预期工作。

      【讨论】:

        【解决方案5】:

        当默认日期为 DateTime.Now 时,您可以在 EditorTemplates 和 Date.cshtml 中使用 kendo ui 组件

        @using Kendo.Mvc.UI
        @model DateTime?
            @if (Model.ToString() == "0001-01-01T00:00:00")
            {
                @Html.Kendo().DatePickerFor(m => m).Format("yyyy/MM/dd").HtmlAttributes(new {style = "width: 20em", type = "text" }).Value(DateTime.Now).Footer("Today -  #=kendo.toString(data, 'dddd  yyyy/MM/dd') #")
            }
            else
            {
                @Html.Kendo().DatePickerFor(m => m).Format("yyyy/MM/dd").HtmlAttributes(new {style = "width: 20em", type = "text"}).Value(Model).Footer("Today-  #=kendo.toString(data, 'dddd  yyyy/MM/dd') #")
            }
        

        在视图模型类中使用

        [UIHint("Date")]
        public DateTime CreateDate { get; set; }
        

        【讨论】:

          【解决方案6】:

          为了扩展 Axel Bouttelgier 的答案,代码如下所示:

          服务器端代码

          [Display(Name = "Disconnect Service")]
          [Range(typeof(DateTime), "01/01/1900", "01/01/2100" )]
          public DateTime Disconnect Service { get; set; }
          

          查看代码

          @Html.ValidationSummary()
          

          验证将如下所示:

          【讨论】:

            猜你喜欢
            • 2018-10-13
            • 2013-02-19
            • 2013-10-02
            • 1970-01-01
            • 1970-01-01
            • 2021-12-10
            • 2011-12-02
            • 1970-01-01
            • 2020-04-10
            相关资源
            最近更新 更多