在MVC中为实体进行自定义验证我实现了IValidatableObject
接口。
现在,在验证代码中,我希望在创建实体时执行某些操作,如果正在更新,则需要执行其他操作。以下面的代码作为我想要的例子:
public partial class ActividadProyecto : IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (IsBeingCreated)
{
// Do stuff
}
else if(IsBeingUpdated)
{
// Do other stuff
}
}
}
有可能吗?我搜索了很多,并没有接近这个。我找到的唯一解决方案是为Create进程创建一个ViewModel,为Update进程创建另一个进程,然后为它们创建独立的验证器:这只是疯狂的错误和丑陋。
提前致谢!
答案 0 :(得分:4)
通过覆盖ValidateEntity()
中的DbContext
方法,您可以通过Validate()
字典对象将所需信息传递给实体的validationContext.Items
方法。
的DbContext:
public class YourDbContext : DbContext
{
// other code
protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
{
items["is_data_layer"] = true;
items["is_insert"] = this.Entry(entityEntry.Entity).State == EntityState.Added;
return base.ValidateEntity(entityEntry, items);
}
}
来自您实体的用法:
public partial class ActividadProyecto : IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
object dummy;
// skip logic if "Validate" is not called from EF...
if (validationContext.Items.TryGetValue("is_data_layer", out dummy))
{
if ((bool)validationContext.Items["is_insert"]) // insert mode
{
// Do stuff
}
else // update mode
{
// Do other stuff
}
}
}
}
修改强>:
我承认我从纯粹的EF(数据层)角度回答。我不是ASP.NET MVC专家。但正如mo.esmp
指出的那样,如果您还将EF实体用作&#34;视图模型&#34;,那么MVC框架将也调用Validate()
方法来验证视图层中的实体。只有在之后,EF才会调用Validate
方法。这样就可以解释为什么您的实体的Validate
方法在上下文的ValidateEntity
方法之前被称为。
那么,问题就变成了:您对增加的逻辑感兴趣的是哪种验证?是否要将逻辑添加到&#34;视图层&#34;验证?或者你想在&#34;数据层中应用你的逻辑&#34; (EF)验证?
我没有足够的细节来回答这个问题。但是如果你只需要在&#34;数据层中添加你的逻辑&#34; (EF)验证阶段,然后我调整了上面的示例代码,如果EF没有调用验证,则跳过逻辑。你可以尝试一下。
答案 1 :(得分:1)
当您将表单发布到服务器时,ASP.NET MVC模型绑定器会尝试绑定Form
到ActividadProyecto
实体,并且将执行IValidatableObject.Validate
方法以验证您的模型,但是您尝试保存实体,将执行EF ValidateEntity
方法。所以在IValidatableObject.Validate
方法中,您无法确定天气实体是否已创建或更新,因为它发生在EF ValidateEntity
方法之前。