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

标签 c# .net entity-framework validation data-annotations

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

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

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

还有我的自定义验证:

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

想法是只使用注解 [isUnique],方法采用带注解的类并搜索相应的实体。

最佳答案

写Validation Attributes时,可以使用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;
}

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

[IsUnique]
YourProperty { get; set; }

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

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

最好只使用可以离线验证的属性来验证实体的这些方面。

诸如 StringLength、RegularExpression、Required 之类的验证属性是良好属性的示例,而检查唯一性或其他数据库相关规则的验证属性是不适当属性的示例。

关于c# - 自定义验证唯一属性 - 泛型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32172157/

相关文章:

c# - 以下是加密算法吗?如果是这样,它是可逆的吗?

c# - ASP.NET 核心 2.1 : Navigating back to a page after an HTTP POST fails validation displays a browser error

c# - Console.WriteLine ('single quote' ); 之间有什么区别?和 Console.WriteLine ("double quote");

c# - 双字结果的高​​效长乘法

c# - 如果我输入搜索参数,如何让机器人框架机器人发回数据库的单元格?

.net - 如何使用默认为 DateTimeKind.Utc 的 DateTime 值进行 DataSet.Fill?

.net - 从 Windows 通过 Entity Framework 连接到 Informix 的问题

c# - ASP.NET MVC Entity Framework 延迟加载或 ViewModel?

c# - 来自 wcf 数据服务的 Entity Framework 6 数据上下文

c# - UWP 有没有在 Canvas 中实现调整大小和移动文本框的控件?