自定义验证属性在编辑记录时不起作用

Custom validation attribute does not work when editing a record

我有一个名为 Doctor 的实体,在创建医生表单中我添加了如下自定义验证逻辑:

public class UniqueDoctorNameAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        string name = value.ToString();
        HospitalEntities db = new HospitalEntities();
        int count = db.Doctors.Where(d => d.DoctorName == name).ToList().Count;
        if (count != 0)
            return new ValidationResult("A doctor already exists with that name");
        return ValidationResult.Success;
    }
}

然后在 Doctor 模型中 class:

public class Doctor
{
    [Required]
    [Display(Name = "Name")]
    [UniqueDoctorName]
    public string DoctorName { get; set; }
}

它在创建医生时按预期工作,但它也显示在 Doctor 的编辑表单中,我知道一种补救方法是在创建表单中使用视图模型并在那里进行验证,但这需要我自己进行了大量调试,因为我编写了很多代码,具体取决于它是否通过了 Doctor 模型,那么我该如何解决这个问题?

您可以更新您的自定义验证属性以接受您的 ID 属性,这样您就可以在对数据库进行检查时使用它。

public class UniqueDoctorNameAttribute : ValidationAttribute
{
    private readonly string _IdPropertyName;

    public UniqueDoctorNameAttribute(string IdPropertyName)
    {
        _IdPropertyName = IdPropertyName;
    }
    protected override ValidationResult IsValid(object value,
                                                      ValidationContext validationContext)
    {
        string name = value.ToString();
        var property = validationContext.ObjectType.GetProperty(_IdPropertyName);
        if (property != null)
        {
            var idValue = property.GetValue(validationContext.ObjectInstance, null);
            var db = new HospitalEntities();
            var exists = db.Doctors.Any(d => d.DoctorName == name && d.Id!=idValue);
            if (exists )
                   return new ValidationResult("A doctor already exists with that name");

            return ValidationResult.Success;
        }
        return ValidationResult.Success;
    }
}

当用户创建新记录时,DoctorId 的值将为 0,而在编辑时它将是一个有效的 doctorId 值。

现在在您的视图模型中,

public class Doctor
{
    public int DoctorId { set; get; }

    [Required]
    [Display(Name = "Name")]
    [UniqueDoctorName(nameof(DoctorId))]
    public string DoctorName { get; set; }
}

nameof 将 return 一个字符串 "DoctorId"( 属性 的名称)。如果你的c#版本不支持这个关键字,只需使用字符串"DoctorId"作为构造函数参数。