日期的MVC模型validation
MVC 5是否有默认validation,我可以设置日期的最小值和最大值?
在我的模型中,我想要日期validation
public class MyClass { [Required(ErrorMessage="Start date and time cannot be empty")] //validate:Must be greater than current date [DataType(DataType.DateTime)] public DateTime StartDateTime { get; set; } [Required(ErrorMessage="End date and time cannot be empty")] //validate:must be greater than StartDate [DataType(DataType.DateTime)] public DateTime EndDateTime { get; set; } }
Ps:根据这个Asp.Net网站 ,使用Range
validation器进行DateTime时出现问题,不推荐使用。
注意:jQueryvalidation不适用于Range属性和DateTime。 例如,以下代码将始终显示客户端validation错误,即使日期在指定范围内:
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
您需要禁用jQuery日期validation以将Range属性与DateTime一起使用。 在模型中编译硬日期通常不是一个好习惯,因此不鼓励使用Range属性和DateTime。
我也知道有像Fluent Validation和Foolproof这样的Nuget软件包可以validation和检查一个日期是否比其他日期更大,但我想知道默认情况下是否有东西可以检查日期的最小值和最大值。
从我在MVC 5.1中的Whats new中看到的,支持MaxLength
和MinLength
validation。
没有必要禁用jQuery日期validation(这可能会导致其他问题)。 您只需要覆盖$.validator
的range
方法。
默认情况下,它使用数值(然后回退到字符串比较),因此您可以添加以下脚本(在jquery.validate.js
和jquery.validate.unobtrusive.js
,但不包含在$(document).ready
$.validator.methods.range = function(value, element, param) { if ($(element).attr('data-val-date')) { var min = $(element).attr('data-val-range-min'); var max = $(element).attr('data-val-range-max'); var date = new Date(value).getTime(); var minDate = new Date(min).getTime(); var maxDate = new Date(max).getTime(); return this.optional(element) || (date >= minDate && date <= maxDate); } // use the default method return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] ); };
然后,您可以在属性上使用RangeAttribute
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")] public DateTime Date { get; set; }
我将使用System.ComponentModel.DataAnnotations中的IValidatableObject
接口执行此操作,该接口允许您添加额外的validation规则,您可以在其中进行更多检查。 将接口添加到您的类,然后实现Validate
方法,您可以将StartDateTime与当前日期/时间进行比较,并将EndDateTime与StartDateTime进行比较,例如
public class MyClass : IValidatableObject { [Required(ErrorMessage="Start date and time cannot be empty")] //validate:Must be greater than current date [DataType(DataType.DateTime)] public DateTime StartDateTime { get; set; } [Required(ErrorMessage="End date and time cannot be empty")] //validate:must be greater than StartDate [DataType(DataType.DateTime)] public DateTime EndDateTime { get; set; } public IEnumerable Validate(ValidationContext validationContext) { List results = new List (); if (StartDateTime < DateTime.Now) { results.Add(new ValidationResult("Start date and time must be greater than current time", new []{"StartDateTime"})); } if (EndDateTime <= StartDateTime) { results.Add(new ValidationResult("EndDateTime must be greater that StartDateTime", new [] {"EndDateTime"})); } return results; } }
唯一可能的缺点是Validate
运行服务器端,而不是jQueryvalidation。
通常我想在服务器中validation某些内容时使用此解决方案。 我知道您可以依赖MVC使用的validation模型,但是当我进行validation时,我正在尝试使用单独的项目,以防我需要对它们进行unit testing。 假设你有两个应用程序,一个桌面和一个Web,然后两个都可以共享ValidationProject,而不是在同一个“View”/“Screen”的两个应用程序中重复代码。 这里的想法是将validation项目作为您解决方案的独立项目。
所以你可以从NuGet下载FluentValidation项目,FluentValidation在构造函数中使用Rules,你可以在这里看到文档https://github.com/JeremySkinner/FluentValidation/wiki
您的日期规则可以通过这种方式使用,例如,您可以为最小值和最大值设置规则:
public class CustomerValidator: AbstractValidator { public CustomerValidator() { RuleFor(customer => customer.startDate) .NotNull() .WithMessage("You should select a start date") .Must(d => d.HasValue && d.Value <= DateTime.Today) .WithMessage("The start date should not be greather than current month/year"); }
现在在你的控制器内
[HttpPost] public ActionResult Index(Customer c) { if(ModelState.IsValid) { var validator= new CustomerValidator(); var valResult = validator.Validate(c); if (valResult.Errors.Count != 0) { valResult.Errors.ForEach(x => ModelState.AddModelError(x.PropertyName, x.ErrorMessage)); return View(vm); } //Your code here } }
我认为只需添加“Range”属性即可
[Range(typeof(DateTime), "01/01/1900", "06/06/2079", ErrorMessageResourceType = typeof(Resources.Patient), ErrorMessageResourceName = "DateOfBirth_Range")]