我有一个场景,我想在ValidationContext中添加一个项目,并在EF触发的实体验证中检查它.我在向导中执行此操作,因此我只能在特定步骤上验证某些内容.(如果有一个好的模式,请分享它).
问题是在控制器操作被击中之前,实际上会触发两次验证.我希望我理解为什么.在发生这种情况之前,我不确定如何在ValidationContext中获取该项,因此我无法告诉验证我正在进行哪一步.
此外,如果我只通过在下面的代码中检查项目来触发保存更改时才进行自定义验证,那么当页面刷新时我不会显示自动模型验证错误.
在我的自定义环境中:
public WizardStep Step { get; set; }
protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
{
items.Add("ValidationStep", Step);
return base.ValidateEntity(entityEntry, items);
}
Run Code Online (Sandbox Code Playgroud)
设置实体的服务:
public void SaveChanges(WizardStep step)
{
_context.Step = step;
_context.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
在我的实体
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// Step will only be present when called from save changes. Calls from model state validation won't have it
if (validationContext.Items.ContainsKey("ValidationStep"))
{
var validationStep = (WizardStep)validationContext.Items["ValidationStep"];
if (validationStep == WizardStep.Introduction)
{
if (criteria)
{
yield return new …Run Code Online (Sandbox Code Playgroud) 我有一个模特课.相关数据库表对两个字段(例如Column1和Column2)具有唯一约束.我不确定在保存对象之前验证对象的最佳方法是什么.
我正在考虑实现IValidatableObject并在Validate方法中进行此验证.这是个好主意吗?我不确定,因为它需要从实体类中的DB读取数据.
public class Class1 :IValidatableObject
{
[Key]
public int ID { get; set; }
[Required]
public int Column1 { get; set; }
[Required]
public int Column2 { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
using (DatabaseContext db = new DatabaseContext())
{
//access DB to check if this combination of Column1 and Column2 already exists
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用MVC4和EF 4.4.
UPDATE
您是否建议使用单独的验证器类而不是使用验证属性?
我需要一个关于该怎么做的建议.我目前正在使用WebSecurity方法来完成所有与帐户相关的工作.但它不支持电子邮件唯一性验证,所以我有几个选择:
编写(子类)新的SimpleMembershipProvider,覆盖现有的createuserAndAccount方法以验证电子邮件地址.但我还必须实现登录注销功能(就像websecurity一样)和其他一些功能.
在数据库上添加唯一性约束并在我的代码上捕获它们.但是这会导致我依赖于数据库.
这可能有点便宜,但我可以将WebSecurity源代码(自打开以来)复制/粘贴到新类上,并修改createUserAndAccount方法.
还有其他选择吗?我目前的目标是选择3,这将是最快的方式.另外,关于未来我也将要求角色,我不确定WebSecurity是否为它们提供支持.
asp.net-mvc asp.net-membership asp.net-mvc-4 simplemembership
我想使用EF 5模型验证来避免数据库中的重复值,所以我使用这样的模型类:
[Table("MeasureUnits")]
public class MeasureUnit : IValidatableObject
{
public int MeasureUnitId { get; set; }
public string Symbol { get; set; }
public string Name { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
using (MeasureUnitRepository rep = new MeasureUnitRepository())
{
MeasureUnit measureUnit = rep.FindDuplicateBySymbol(this);
if (measureUnit != null)
yield return new ValidationResult(
"There is another unit with this symbol, you can't duplicate it",
new[] { "Symbol" });
}
}
Run Code Online (Sandbox Code Playgroud)
存储库类创建DbContext,实现IDisposable,具有查找副本的逻辑,它都可以正常工作.
但是,使用调试器我意识到每次插入或更新都会执行两次验证,因此存储库(和DbContext)也会被实例化并处理两次.
除此之外,还有另一个DbContext存在于控制器中但只是在模型类中找不到使用它的方法,除了在模型的构造函数中包含DbContext,但我觉得它不是正确的解决方案.
是否有更好的"正确"方式来实现此验证?
提前致谢.