如何在自定义验证属性中获取模型实例
How to get model instance in a custom validation attribute
我正在使用 asp.net 核心 2.0,并且我有一个用于验证年龄的自定义验证属性。
public class ValidAgeAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var model = validationContext.ObjectInstance as FormModel;
var db = model.DOB.AddYears(100);
if (model == null)
throw new ArgumentException("Attribute not applied on Model");
if (model.DOB > DateTime.Now.Date)
return new ValidationResult($"{validationContext.DisplayName} can't be in future");
if (model.DOB > DateTime.Now.Date.AddYears(-16))
return new ValidationResult("You must be 17 years old.");
if (db < DateTime.Now.Date)
return new ValidationResult("We rescept you but we cannot accept this date. over 100 years old.");
return ValidationResult.Success;
}
}
但此属性取决于我的 "FormModel" class,这是我的领域模型 class。
public class FormModel
{
[Required, Display(Name = "Date of Birth")]
[ValidAge]
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime DOB { get; set; }
}
我希望此属性不依赖于 "FormModel" class,如图所示 here.So 我能否以某种方式获取我正在使用此属性的模型的实例,而无需硬编码此处为模特姓名?
这里有两种无需硬编码模型名称的简单方法,如下所示:
1.The 第一种方式:
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var model = (DateTime)value;
var db = model.AddYears(100);
if (model == null)
throw new ArgumentException("Attribute not applied on Model");
if (model > DateTime.Now.Date)
return new ValidationResult($"{validationContext.DisplayName} can't be in future");
if (model > DateTime.Now.Date.AddYears(-16))
return new ValidationResult("You must be 17 years old.");
if (db < DateTime.Now.Date)
return new ValidationResult("We rescept you but we cannot accept this date. over 100 years old.");
return ValidationResult.Success;
}
2.The第二种方式:
public class FormModel: IValidatableObject
{
[Required, Display(Name = "Date of Birth")]
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime DOB { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var data = DOB.AddYears(100);
if (DOB> DateTime.Now.Date)
{
yield return new ValidationResult("Date of Birth can't be in future");
yield break;
}
if (DOB> DateTime.Now.Date.AddYears(-16))
{
yield return new ValidationResult("You must be 17 years old.");
yield break;
}
if (data < DateTime.Now.Date)
{
yield return new ValidationResult("We rescept you but we cannot accept this date. over 100 years old.");
yield break;
}
}
}
我正在使用 asp.net 核心 2.0,并且我有一个用于验证年龄的自定义验证属性。
public class ValidAgeAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var model = validationContext.ObjectInstance as FormModel;
var db = model.DOB.AddYears(100);
if (model == null)
throw new ArgumentException("Attribute not applied on Model");
if (model.DOB > DateTime.Now.Date)
return new ValidationResult($"{validationContext.DisplayName} can't be in future");
if (model.DOB > DateTime.Now.Date.AddYears(-16))
return new ValidationResult("You must be 17 years old.");
if (db < DateTime.Now.Date)
return new ValidationResult("We rescept you but we cannot accept this date. over 100 years old.");
return ValidationResult.Success;
}
}
但此属性取决于我的 "FormModel" class,这是我的领域模型 class。
public class FormModel
{
[Required, Display(Name = "Date of Birth")]
[ValidAge]
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime DOB { get; set; }
}
我希望此属性不依赖于 "FormModel" class,如图所示 here.So 我能否以某种方式获取我正在使用此属性的模型的实例,而无需硬编码此处为模特姓名?
这里有两种无需硬编码模型名称的简单方法,如下所示:
1.The 第一种方式:
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var model = (DateTime)value;
var db = model.AddYears(100);
if (model == null)
throw new ArgumentException("Attribute not applied on Model");
if (model > DateTime.Now.Date)
return new ValidationResult($"{validationContext.DisplayName} can't be in future");
if (model > DateTime.Now.Date.AddYears(-16))
return new ValidationResult("You must be 17 years old.");
if (db < DateTime.Now.Date)
return new ValidationResult("We rescept you but we cannot accept this date. over 100 years old.");
return ValidationResult.Success;
}
2.The第二种方式:
public class FormModel: IValidatableObject
{
[Required, Display(Name = "Date of Birth")]
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime DOB { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var data = DOB.AddYears(100);
if (DOB> DateTime.Now.Date)
{
yield return new ValidationResult("Date of Birth can't be in future");
yield break;
}
if (DOB> DateTime.Now.Date.AddYears(-16))
{
yield return new ValidationResult("You must be 17 years old.");
yield break;
}
if (data < DateTime.Now.Date)
{
yield return new ValidationResult("We rescept you but we cannot accept this date. over 100 years old.");
yield break;
}
}
}