获取导致 DbEntityValidationException 的 ValidationAttribute 类型
Get Type of ValidationAttribute causing a DbEntityValidationException
我正在使用依赖于 System.ComponentModel.DataAnnotations.ValidationAttribute
的 Entity Framework 的验证。因此,当我调用 DbContext.SaveChanges()
并且实体 属性 验证失败时,将抛出 DbEntityValidationException
。
我需要知道的是 ValidationAttribute
究竟是哪个 ValidationAttribute
导致了验证错误。 即我需要知道 ValidationAttribute
的 Type
在我的程序中导致 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
注释是否触发了验证错误?
我想你要找的是Validator.TryValidateObject
静态方法:
var modelToSave = new Model { Code = "ThisIsTooLong" };
var results = new List<ValidationResult>();
bool isValid=Validator.TryValidateObject( modelToSave, context, results, true);
如果您的实体无效,您将在 results
列表中保留每个失败的验证。
更新
好吧,使用 ErrorMessage
获取 ValidationAttribute
的通用解决方案可能是这样做的:
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;
}
如果您使用的是 Entity Framework 4.1+,这可能对您有所帮助。您可以在您的实体中实施您自己的验证逻辑,并且 return 您自己的错误代码用于不同的验证问题。
IValidatableObject is an interface that lives in System.ComponentModel.DataAnnotations. While it is not part of the Entity Framework API, you can still leverage it for server-side validation in your Entity Framework classes. IValidatableObject provides a Validate method that Entity Framework will call during SaveChanges or you can call yourself any time you want to validate the classes.
Configurations such as Required and MaxLength perform validaton on a single field. In the Validate method you can have even more complex logic, for example, comparing two fields.
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” });
}
}
}
我正在使用依赖于 System.ComponentModel.DataAnnotations.ValidationAttribute
的 Entity Framework 的验证。因此,当我调用 DbContext.SaveChanges()
并且实体 属性 验证失败时,将抛出 DbEntityValidationException
。
我需要知道的是 ValidationAttribute
究竟是哪个 ValidationAttribute
导致了验证错误。 即我需要知道 ValidationAttribute
的 Type
在我的程序中导致 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
注释是否触发了验证错误?
我想你要找的是Validator.TryValidateObject
静态方法:
var modelToSave = new Model { Code = "ThisIsTooLong" };
var results = new List<ValidationResult>();
bool isValid=Validator.TryValidateObject( modelToSave, context, results, true);
如果您的实体无效,您将在 results
列表中保留每个失败的验证。
更新
好吧,使用 ErrorMessage
获取 ValidationAttribute
的通用解决方案可能是这样做的:
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;
}
如果您使用的是 Entity Framework 4.1+,这可能对您有所帮助。您可以在您的实体中实施您自己的验证逻辑,并且 return 您自己的错误代码用于不同的验证问题。
IValidatableObject is an interface that lives in System.ComponentModel.DataAnnotations. While it is not part of the Entity Framework API, you can still leverage it for server-side validation in your Entity Framework classes. IValidatableObject provides a Validate method that Entity Framework will call during SaveChanges or you can call yourself any time you want to validate the classes.
Configurations such as Required and MaxLength perform validaton on a single field. In the Validate method you can have even more complex logic, for example, comparing two fields.
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” });
}
}
}