C#自定义验证唯一属性 - 泛型类

grt*_*ibo 8 .net c# validation entity-framework data-annotations

我正在尝试进行自定义验证[IsUnique].检查属性值是否唯一并返回正确的消息.

这是我的代码,但这只适用于指定的类,是否可以通过元数据来获取正确的类?

public class ArticleMetaData
    {
        [Required(AllowEmptyStrings = false)]
        [IsUnique("Name")]
        public String Name{ get; set; }      
    }
Run Code Online (Sandbox Code Playgroud)

我的自定义验证:

class IsUnique : ValidationAttribute
    {
        public IsUnique(string propertyNames)
        {
            this.PropertyNames = propertyNames;
        }

        public string PropertyNames { get; private set; }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {

            var myproperty = validationContext.ObjectType.GetProperty(PropertyNames);
            var value = propiedad.GetValue(validationContext.ObjectInstance, null);

            IEnumerable<String> properties;

            List<string> propertiesList = new List<string>();
            propertiesList.Add(myproperty.Name);

            var dba = new myContext();

            if (dba.Articles.Any(article => article.Name == (string)value))
            {
                return new ValidationResult("The name already exist", propertiesList);
            }
            return null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我们的想法是只使用注释[isUnique],该方法将带有注释的类并搜索相应的实体.

Rez*_*aei 5

编写验证属性时,可以使用ValidationContext获取有关验证的一些信息,例如要验证的属性名称,要验证的对象类型等.

因此,您不需要声明要检查哪个属性的唯一性,或者应该检查哪个实体,或者您不需要使用反射检索值的事件,因为该值已传递给IsValid方法.

使用DbContext时,您可以执行Sql查询,因此您可以使用sql查询简单地检查唯一性.它比尝试动态创建通用linq查询更简单.

可能这个想法可以帮到你.根据这个想法,您的代码中有一些更改:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    var db = new YourDBContext();

    var className = validationContext.ObjectType.Name.Split('.').Last();
    var propertyName = validationContext.MemberName;
    var parameterName = string.Format("@{0}", propertyName);

    var result = db.Database.SqlQuery<int>(
        string.Format("SELECT COUNT(*) FROM {0} WHERE {1}={2}", className, propertyName, parameterName),
        new System.Data.SqlClient.SqlParameter(parameterName, value));
    if (result.ToList()[0] > 0)
    {
        return new ValidationResult(string.Format("The '{0}' already exist", propertyName),
                    new List<string>() { propertyName });
    }

    return null;
}
Run Code Online (Sandbox Code Playgroud)

要使用此属性,只需将[IsUnique]放在属性上方即可.

[IsUnique]
YourProperty { get; set; }
Run Code Online (Sandbox Code Playgroud)

然后使用这样的代码运行测试:

var db = new YourDbContext();
db.Configuration.ValidateOnSaveEnabled = true;
db.Categories.Add(new YourEntity() { YourProperty = "DuplicateName" });
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

使用可以离线验证的属性仅验证实体的此类方面是一种很好的做法.

验证属性如StringLength,RegularExpression,Required和此类验证是良好属性的示例,检查uniqness或其他数据库相关规则的验证属性是不适当属性的示例.