EF Core 没有引发 ValidationException
EF Core not raising ValidationException
我有一个基础DbContext
class喜欢
public abstract class DbContextBase : DbContext
{
public DbContextBase()
{
}
public DbContextBase(DbContextOptions options)
: base(options)
{
}
public override int SaveChanges()
{
this.ValidateEntities();
return base.SaveChanges();
}
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
this.ValidateEntities();
return base.SaveChangesAsync(cancellationToken);
}
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
{
this.ValidateEntities();
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
protected virtual void ValidateEntities()
{
var entities = this.ChangeTracker.Entries().
Where(s => s.State == EntityState.Added || s.State == EntityState.Modified);
foreach (var entity in entities)
{
var validationContext = new ValidationContext(entity);
Validator.ValidateObject(entity, validationContext);
}
}
}
我所有的 Db 上下文 class 都继承自这个基础 class。问题是即使存在验证违规,行 Validator.ValidateObject()
也不会抛出 ValidationException
。在调试器中,我可以看到该行已执行。例如,对于下面的模型 class 我尝试调用 SaveChangesAsync()
并将 Name
设置为 null
但验证通过:
public class MyModel : IEntity<long>
{
[Key]
public long Id { get; set; }
[Required]
public string Name { get; set; }
}
IEntity<T>
只是对所有模型施加 属性 Id
。
代码
public class MyModel : IEntity<long>
{
[Key]
public long Id { get; set; }
[Required(AllowEmptyStrings = false)]
public string Name { get; set; }
}
更多
c# - MVC not validate empty string - Stack Overflow
问题是变量 entity
不包含实体实例,而是更改跟踪器 (EntityEntry
) 实例,因此代码试图验证错误的东西。
所以要么重命名变量并使用 entry.Entity
属性:
var entries = this.ChangeTracker.Entries()
.Where(s => s.State == EntityState.Added || s.State == EntityState.Modified);
foreach (var entry in entries)
{
var validationContext = new ValidationContext(entry.Entity);
Validator.ValidateObject(entry.Entity, validationContext);
}
或保持代码不变,但要确保 entities
变量包含可枚举的实体实例:
var entities = this.ChangeTracker.Entries()
.Where(s => s.State == EntityState.Added || s.State == EntityState.Modified)
.Select(s => s.Entity); // <--
我有一个基础DbContext
class喜欢
public abstract class DbContextBase : DbContext
{
public DbContextBase()
{
}
public DbContextBase(DbContextOptions options)
: base(options)
{
}
public override int SaveChanges()
{
this.ValidateEntities();
return base.SaveChanges();
}
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
this.ValidateEntities();
return base.SaveChangesAsync(cancellationToken);
}
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
{
this.ValidateEntities();
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
protected virtual void ValidateEntities()
{
var entities = this.ChangeTracker.Entries().
Where(s => s.State == EntityState.Added || s.State == EntityState.Modified);
foreach (var entity in entities)
{
var validationContext = new ValidationContext(entity);
Validator.ValidateObject(entity, validationContext);
}
}
}
我所有的 Db 上下文 class 都继承自这个基础 class。问题是即使存在验证违规,行 Validator.ValidateObject()
也不会抛出 ValidationException
。在调试器中,我可以看到该行已执行。例如,对于下面的模型 class 我尝试调用 SaveChangesAsync()
并将 Name
设置为 null
但验证通过:
public class MyModel : IEntity<long>
{
[Key]
public long Id { get; set; }
[Required]
public string Name { get; set; }
}
IEntity<T>
只是对所有模型施加 属性 Id
。
代码
public class MyModel : IEntity<long>
{
[Key]
public long Id { get; set; }
[Required(AllowEmptyStrings = false)]
public string Name { get; set; }
}
更多
c# - MVC not validate empty string - Stack Overflow
问题是变量 entity
不包含实体实例,而是更改跟踪器 (EntityEntry
) 实例,因此代码试图验证错误的东西。
所以要么重命名变量并使用 entry.Entity
属性:
var entries = this.ChangeTracker.Entries()
.Where(s => s.State == EntityState.Added || s.State == EntityState.Modified);
foreach (var entry in entries)
{
var validationContext = new ValidationContext(entry.Entity);
Validator.ValidateObject(entry.Entity, validationContext);
}
或保持代码不变,但要确保 entities
变量包含可枚举的实体实例:
var entities = this.ChangeTracker.Entries()
.Where(s => s.State == EntityState.Added || s.State == EntityState.Modified)
.Select(s => s.Entity); // <--