我正在使用依赖于System.ComponentModel.DataAnnotations.ValidationAttribute
s的实体框架的验证。因此,当我调用DbContext.SaveChanges()
并且实体属性验证失败时,会抛出DbEntityValidationException
。
我需要知道的是ValidationAttribute
确切地导致了验证错误。的即。我需要知道Type
ValidationAttribute
导致我的计划中出现DbEntityValidationException
。
我已经知道如何遍历DbEntityValidationException
内的验证错误集合。但是,所需的信息不在那里。
示例
假设我有一个带有单个属性的简单模型,该属性有两个数据注释......
class Model
{
[Required]
[MaxLength(3)]
string Code { ... }
}
...并希望像这样添加一个新的实例:
try
{
var model = new Model { Code = "ThisIsTooLong" };
dbContext.Set<Model>().Add(model);
dbContext.SaveChanges();
}
catch (DbEntityValidationException e)
{
Type unsatisfiedValidationAttribute = MagicFunction();
}
在上述情况下,会引发DbEntityValidationException
,变量unsatisfiedValidationAttribute
应等于typeof(MaxLengthAttribute)
。
MagicFunction()
必须了解Required
或MaxLength
注释是否触发了验证错误?
答案 0 :(得分:1)
我认为你要找的是Validator.TryValidateObject
静态方法:
var modelToSave = new Model { Code = "ThisIsTooLong" };
var results = new List<ValidationResult>();
bool isValid=Validator.TryValidateObject( modelToSave, context, results, true);
如果您的实体无效,您将在results
列表中保留每个失败的验证。
嗯,使用ValidationAttribute
获取ErrorMessage
的通用解决方案可以这样做:
public static ValidationAttribute GetAttribute(Type entityType, string property, string errorMessage)
{
var attributes = typeof(entityType)
.GetProperty(property)
.GetCustomAttributes(false)
.OfType<ValidationAttribute>()
.ToArray();
var attribute= attributes.FirstOrDefault(a => a.ErrorMessage == errorMessage);
return attribute;
}
答案 1 :(得分:0)
如果您使用的是Entity Framework 4.1+,这可能对您有所帮助。您可以在实体中实现自己的验证逻辑,并返回自己的错误代码以解决不同的验证问题。
IValidatableObject是一个存在于System.ComponentModel.DataAnnotations中的接口。虽然它不是Entity Framework API的一部分,但您仍可以将其用于Entity Framework类中的服务器端验证。 IValidatableObject提供Entity Framework将在SaveChanges期间调用的Validate方法,或者您可以在任何时候想要验证类时自行调用。
诸如Required和MaxLength之类的配置在单个字段上执行验证。在Validate方法中,您可以拥有更复杂的逻辑,例如,比较两个字段。
public class Blog : IValidatableObject
{
public int Id { get; set; }
[Required]
public string Title { get; set; }
public string BloggerName { get; set; }
public DateTime DateCreated { get; set; }
public virtual ICollection<Post> Posts { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Title == BloggerName)
{
yield return new ValidationResult
("Blog Title cannot match Blogger Name", new[] { "Title", “BloggerName” });
}
}
}