如何使用多个属性依赖项创建自定义验证

时间:2016-10-28 10:10:46

标签: c# winforms entity-framework validation data-annotations

我正在努力验证某些价值观,我希望有人能指出我正确的方向。

考虑下面的类(它已被简化,省略了问题解决方案的不需要的列):

using System;
using System.Collections.Generic;

public partial class Data_Header
{
    public Data_Header()
    {
        this.Data_Lines = new HashSet<Data_Lines>();
    }

    public int DataHeaderID { get; set; }
    public System.Guid CmpWwn { get; set; }
    public System.Guid CntId { get; set; }
    public System.DateTime DeliveryDate { get; set; }
    public Nullable<int> DeliveryMethod_SysDeliveryMethodsID { get; set; }
    public System.DateTime DueDate { get; set; }

    public virtual Sys_DeliveryMethods Sys_DeliveryMethods { get; set; }
    public virtual vw_cicmpy vw_cicmpy { get; set; }
    public virtual ICollection<Data_Lines> Data_Lines { get; set; }
}

我为CmpWwn和CntId创建验证所做的是创建一个名为RequiredGuidAttribute的自定义属性,我在StackOverflow上找到了它:

public class RequiredGuidAttribute : RequiredAttribute
{
    public override bool IsValid(object value)
    {
        var guid = CastToGuidOrDefault(value);

        return !Equals(guid, default(Guid));
    }

    private static Guid CastToGuidOrDefault(object value)
    {
        try
        {
            return (Guid)value;
        }
        catch (Exception e)
        {
            if (e is InvalidCastException || e is NullReferenceException) return default(Guid);
            throw;
        }
    }
}

因此,我可以使用此注释来验证Guid值。这不是很困难,我理解这个原则。现在是下一期:

我想确保DueDate的值永远不会超过当前日期,也不会超过DeliveryDate属性的值,甚至更多,DueDate的值应该是基于DeliveryMethod的计算值

我很茫然;如何创建这样的验证?我知道我可以简单地使用一个带有一些if语句返回true或false的方法,但是如果可能的话我想使用数据注释,以便我可以使用相同的错误处理程序。

我在实体框架6中使用数据库优先。

1 个答案:

答案 0 :(得分:1)

确保使用ValidationContext覆盖IsValid以获取对底层对象的访问权限。然后去找你的Guid的DueDate:

public override bool IsValid(object value, ValidationContext validationContext)
{
    var dataHeader = validationContext.ObjectInstance as Data_Header;
    var dueDate = dataHeader.CalculateDueDate;
    bool isValid = false;

    if (dueDate.CompareTo(DateTime.Now) < 0 ||
        dueDate.CompareTo(dataHeader.DeliveryDate) < 0)
    {
       isValid = false;
    }

    return isValid;
}

这样的事情应该这样做。你可以像之前一样处理Guid。如果您调用验证,则在ValidationContext中提供:

例如:

var results = new List<ValidationResult>();
Validator.TryValidateObject(this, new ValidationContext(YOUR_OBJECT_TO_VALIDATE, null, null), results, true);