当继承类的基类也具有验证时,如何对其模型进行验证?

Pal*_*FoX 3 c# inheritance ivalidatableobject asp.net-core

好吧,我的问题是我正在使用 aspnetcore 2.1 创建一个 api,为了避免代码重复,我创建了一个具有共享 dtos 属性的抽象类(board、boardforcreation、boardforupdate 等)。我使用 ivalidatableobject 添加到抽象类个性化验证,现在,我想向从抽象类派生的类添加个性化验证,但它告诉我从 ivalidatableobject 接口扩展是多余的,因为它已经在基类中声明了,而且当我在派生类中添加 Validate 方法时,它告诉我它已经声明并实现了,那么,如何使用 ivalidatableobject 在抽象类和派生类中添加验证?或者还有其他方法可以实现这一目标。先感谢您。

public class Board : BoardAbstractBase, IValidatableObject
{
    public Guid BoardId { get; set; }

    public DateTimeOffset StartDate { get; set; }

    public DateTimeOffset EndDate { get; set; }  
}

public abstract class BoardAbstractBase : AbstractBasicEntity, IValidatableObject
{
    public DateTimeOffset EstimatedStartDate { get; set; }


    public DateTimeOffset EstimatedEndDate { get; set; }


    public decimal EstimatedBudget { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (!(EstimatedStartDate < EstimatedEndDate))
            yield return new ValidationResult(
                "StartDateBeforeEndDate|The estimated start date should be smaller than the end date.",
                new[] {"BoardAbstractBase"});
    }
}
Run Code Online (Sandbox Code Playgroud)

Mat*_*ish 6

虚拟方法添加到您的基类中。

如果您想在基类中执行一些常见的验证逻辑,并在每个具体实现中执行额外的验证逻辑,则可以向基类添加一个在基类验证函数中调用的虚拟验证方法。

添加到您的基类:

public abstract class BoardAbstractBase {
    ...
    protected virtual bool RepoValidate() {
        return true;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后在每个具体实现中RepoValidate使用您需要的任何自定义验证逻辑来​​实现protected override bool RepoValidate() {...}

例如

public class Board : BoardAbstractBase, IValidatableObject
{
    ...
    protected override bool RepoValidate() { 
        return this.BoardId == "";
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后在BoardAbstractBase.Validate

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (!(EstimatedStartDate < EstimatedEndDate))
            yield return new ValidationResult(
                "StartDateBeforeEndDate|The estimated start date should be smaller than the end date.",
                new[] {"BoardAbstractBase"});

        if (!this.RepoValidate()){ ... }
    }
Run Code Online (Sandbox Code Playgroud)

现在,您始终可以修改RepoValidate以在验证失败时返回验证结果,或接受任何参数,但仅为了示例,此仅返回 false。另外,因为它是virtual而不是abstract,所以只有当您有额外的自定义逻辑要执行时才需要覆盖它。