日期的数据注释范围

时间:2009-09-10 15:37:12

标签: c# asp.net-mvc date model-view-controller data-annotations

是否可以对日期使用[Range]注释?

类似

[Range(typeof(DateTime), DateTime.MinValue.ToString(), DateTime.Today.ToString())]

7 个答案:

答案 0 :(得分:60)

我这样做是为了解决你的问题

 public class DateAttribute : RangeAttribute
   {
      public DateAttribute()
        : base(typeof(DateTime), DateTime.Now.AddYears(-20).ToShortDateString(),     DateTime.Now.AddYears(2).ToShortDateString()) { } 
   }

答案 1 :(得分:47)

Docs on MSDN表示您可以使用RangeAttribute

[Range(typeof(DateTime), "1/2/2004", "3/4/2004",
        ErrorMessage = "Value for {0} must be between {1} and {2}")]
public datetime Something { get; set;}

答案 2 :(得分:9)

jQuery验证不适用于[Range(typeof(DateTime),“date1”,“date2”] - 我的MSDN文档不正确

答案 3 :(得分:6)

这是另一种解决方案。

[Required(ErrorMessage = "Date Of Birth is Required")]
[DataType(DataType.Date, ErrorMessage ="Invalid Date Format")]
[Remote("IsValidDateOfBirth", "Validation", HttpMethod = "POST", ErrorMessage = "Please provide a valid date of birth.")]
[Display(Name ="Date of Birth")]
public DateTime DOB{ get; set; }

简单地创建一个名为ValidationController的新MVC控制器并在那里通过此代码。关于" Remote"的好处方法是您可以利用此框架根据您的自定义逻辑处理任何类型的验证。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Mail;
using System.Web;
using System.Web.Mvc;

namespace YOURNAMESPACEHERE
{
    public class ValidationController : Controller
    {
        [HttpPost]
        public JsonResult IsValidDateOfBirth(string dob)
        {
            var min = DateTime.Now.AddYears(-21);
            var max = DateTime.Now.AddYears(-110);
            var msg = string.Format("Please enter a value between {0:MM/dd/yyyy} and {1:MM/dd/yyyy}", max,min );
            try
            {
                var date = DateTime.Parse(dob);
                if(date > min || date < max)
                    return Json(msg);
                else
                    return Json(true);
            }
            catch (Exception)
            {
                return Json(msg);
            }
        }
    }
}

答案 4 :(得分:5)

对于那些在您被迫以字符串形式写日期的情况(使用属性时),我强烈建议您使用ISO-8601表示法。 这消除了关于01/02/2004是1月2日还是2月1日的任何混淆。

[Range(typeof(DateTime), "2004-12-01", "2004-12-31",
    ErrorMessage = "Value for {0} must be between {1} and {2}")]
public datetime Something { get; set;}

答案 5 :(得分:0)

我使用这种方法:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
internal sealed class DateRangeAttribute : ValidationAttribute
{
    public DateTime Minimum { get; }
    public DateTime Maximum { get; }

    public DateRangeAttribute(string minimum = null, string maximum = null, string format = null)
    {
        format = format ?? @"yyyy-MM-dd'T'HH:mm:ss.FFFK"; //iso8601

        Minimum = minimum == null ? DateTime.MinValue : DateTime.ParseExact(minimum, new[] { format }, CultureInfo.InvariantCulture, DateTimeStyles.None); //0 invariantculture
        Maximum = maximum == null ? DateTime.MaxValue : DateTime.ParseExact(maximum, new[] { format }, CultureInfo.InvariantCulture, DateTimeStyles.None); //0 invariantculture

        if (Minimum > Maximum)
            throw new InvalidOperationException($"Specified max-date '{maximum}' is less than the specified min-date '{minimum}'");
    }
    //0 the sole reason for employing this custom validator instead of the mere rangevalidator is that we wanted to apply invariantculture to the parsing instead of
    //  using currentculture like the range attribute does    this is immensely important in order for us to be able to dodge nasty hiccups in production environments

    public override bool IsValid(object value)
    {
        if (value == null) //0 null
            return true;

        var s = value as string;
        if (s != null && string.IsNullOrEmpty(s)) //0 null
            return true;

        var min = (IComparable)Minimum;
        var max = (IComparable)Maximum;
        return min.CompareTo(value) <= 0 && max.CompareTo(value) >= 0;
    }
    //0 null values should be handled with the required attribute

    public override string FormatErrorMessage(string name) => string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, Minimum, Maximum);
}

并像这样使用它:

[DateRange("2004-12-01", "2004-12-2", "yyyy-M-d")]
ErrorMessage = "Value for {0} must be between {1} and {2}")]

答案 6 :(得分:0)

我发现[Range(typeof(DateTime)]批注存在问题,并将其描述为“充其量是笨拙的”,如果该批注有效,则留下太多的机会。

远程验证似乎是一种好方法:避免在视图中使用javascript并维护服务器端代码的完整性,如果可以避免的话,我个人不喜欢将代码发送给客户端以执行。

使用@Stack这个答案作为基础,并参考了article在MVC3中的远程验证

模型

public class SomeDateModel
{
    public int MinYears = 18;
    public int MaxYears = 110;

    [Display(Name = "Date of birth", Prompt = "e.g. 01/01/1900")]
    [Remote(action: "ValidateDateBetweenYearsFromNow", controller: "Validation", areaReference: AreaReference.UseRoot, AdditionalFields = "MinYears,MaxYears", HttpMethod = "GET" ,ErrorMessage = "Subject must be over 18")]
    public DateTime? DOB { get; set; }
}

控制器-部署在根目录

namespace Controllers
{
    public class ValidationController : Controller
    {
        [HttpGet]
        [ActionName("ValidateDateBetweenYearsFromNow")]
        public JsonResult ValidateDateBetweenYearsFromNow_Get()
        {
            //This method expects 3 parameters, they're anonymously declared through the Request Querystring,
            //Ensure the order of params is:
            //[0] DateTime
            //[1] Int Minmum Years Ago e.g. for 18 years from today this would be 18
            //[2] int Maximum Years Ago e.g. for 100 years from today this would be 100
            var msg = string.Format("An error occured checking the Date field validity");
            try
            {
                int MinYears = int.Parse(Request.QueryString[1]);
                int MaxYears = int.Parse(Request.QueryString[2]);

                //Use (0 - x) to invert the positive int to a negative.
                var min = DateTime.Now.AddYears((0-MinYears));
                var max = DateTime.Now.AddYears((0-MaxYears));

                //reset the response error msg now all parsing and assignmenst succeeded.
                msg = string.Format("Please enter a value between {0:dd/MM/yyyy} and {1:dd/MM/yyyy}", max, min);
                var date = DateTime.Parse(Request.QueryString[0]);
                if (date > min || date < max)
                    //switch the return value here from "msg" to "false" as a bool to use the MODEL error message
                    return Json(msg, JsonRequestBehavior.AllowGet);
                else
                    return Json(true, JsonRequestBehavior.AllowGet);
            }
            catch (Exception)
            {
                return Json(msg, JsonRequestBehavior.AllowGet);
            }
        }
    }
}

msg变量显示为Html帮助程序ValidationSummary或​​Html帮助程序ValidationFor(x => x.DATETIME)

查看

重要的是要注意,作为参数2和3传递的字段必须存在于视图中,以便远程验证将值传递给控制器​​:

    @Html.EditorFor(m => m.DOB)
    @Html.HiddenFor(m => m.MinYears)
    @Html.HiddenFor(m => m.MaxYears)
    @Html.ValidationSummary()

模型和HTML帮助器将为您完成所有的jQuery工作。