如何在自定义验证属性中获取模型实例

时间:2019-09-11 14:28:41

标签: asp.net-core asp.net-core-2.0

我正在使用asp.net core 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”类,这是我的域模型类。

 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”类。那么我能以某种方式获取我正在使用该属性的模型的实例,而不必在此处硬编码模型的名称吗?

1 个答案:

答案 0 :(得分:1)

有两种简单的方法,无需对模型名称进行硬编码,如下所示:

1。第一种方式:

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。第二种方式:

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;
        }
    }
}