C# 日期的数据注释范围
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1406046/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Data Annotation Ranges of Dates
提问by Davy
Is it possible to use [Range]
annotation for dates?
是否可以[Range]
对日期使用注释?
something like
就像是
[Range(typeof(DateTime), DateTime.MinValue.ToString(), DateTime.Today.ToString())]
采纳答案by Daniel Elliott
Docs on MSDNsays you can use the RangeAttribute
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;}
回答by MarkKGreenway
I did this to fix your problem
我这样做是为了解决您的问题
public class DateAttribute : RangeAttribute
{
public DateAttribute()
: base(typeof(DateTime), DateTime.Now.AddYears(-20).ToShortDateString(), DateTime.Now.AddYears(2).ToShortDateString()) { }
}
回答by RickAndMSFT
jQuery validation does not work with [Range(typeof(DateTime),"date1","date2"] -- My MSDN doc is incorrect
jQuery 验证不适用于 [Range(typeof(DateTime),"date1","date2"] -- 我的 MSDN 文档不正确
回答by StackThis
Here is another solution.
这是另一种解决方案。
[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; }
The simply create a new MVC controller called ValidationController and past this code in there. The nice thing about the "Remote" approach is you can leverage this framework to handle any kind of validations based on your custom logic.
只需创建一个名为 ValidationController 的新 MVC 控制器,并在其中传递此代码。“远程”方法的好处是您可以利用这个框架来处理基于您的自定义逻辑的任何类型的验证。
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);
}
}
}
}
回答by Tikall
For those rare occurrences when you are forced to write a date as a string (when using attributes), I highly recommend using the ISO-8601notation. That eliminates any confusion as to whether 01/02/2004 is january 2nd or february 1st.
对于那些被迫将日期写入字符串(使用属性时)的罕见情况,我强烈建议使用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;}
回答by XDS
I use this approach:
我使用这种方法:
[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);
}
And use it like so:
并像这样使用它:
[DateRange("2004-12-01", "2004-12-2", "yyyy-M-d")]
ErrorMessage = "Value for {0} must be between {1} and {2}")]
回答by Richard
I found issues with the [Range(typeof(DateTime)]
annotation and would describe it as "clunky at best" it leaves too much to chance IF it works.
我发现[Range(typeof(DateTime)]
注释存在问题,并将其描述为“充其量是笨拙的”,如果它有效,它会留下太多机会。
Remote validation seems to be a good way of: avoiding javascript in views and maintaining server side code integrity, personally never like sending code to a client to execute if I can avoid it.
远程验证似乎是一个很好的方法:避免在视图中使用 javascript 并保持服务器端代码的完整性,如果我可以避免的话,我个人从不喜欢将代码发送到客户端执行。
Using @StackThis answer as a base and reference to an articleon remote validation in MVC3
使用@StackThis 答案作为基础并参考一篇关于 MVC3 中远程验证的文章
Model
模型
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; }
}
Controller - Deployed at the root directory
控制器 - 部署在根目录
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);
}
}
}
}
The msg
variable is displayed as part of the Html helper ValidationSummary or the Html helper ValidationFor(x=>x.DATETIME)
该msg
变量显示为 Html 助手 ValidationSummary 或 Html 助手 ValidationFor(x=>x.DATETIME) 的一部分
View
看法
It's important to note that the fields passed as parameter 2 and 3 must exist in the view in order for the remote validation to pass the values to the controller:
需要注意的是,作为参数 2 和 3 传递的字段必须存在于视图中,以便远程验证将值传递给控制器:
@Html.EditorFor(m => m.DOB)
@Html.HiddenFor(m => m.MinYears)
@Html.HiddenFor(m => m.MaxYears)
@Html.ValidationSummary()
The model and Html helpers will do all the jquery work for you.
模型和 Html 助手将为您完成所有 jquery 工作。