LLBL Gen 3.x 源代码追踪与解析 验证Validation的原理和流程
2011-08-29 09:38
459 查看
先看应用程序如何应用验证。以SalesOrderHeaderEntity为例子。
常见的三种验证:
1)保存之前的验证,重写ValidateEntityBeforeSave
2) 删除前的验证,重写ValidateEntityBeforeDelete
3) 属性获取值之后的验证,重写ValidateFieldValue
先讲解一个基本的模式,基类中的设计virtual方法,派生中中override,我们在运行时,会调用实际类型的方法
public class A
{
public virtual Do() { }
}
public class B: A
{
public override Do() { }
}
当以这种方法调用时
A obj=new B():
obj.Do();
它会根据obj的实际类型,调用对应的方法
public partial class SalesOrderHeaderValidator : ValidatorBase
{
// __LLBLGENPRO_USER_CODE_REGION_START ValidationCode
删除采购单前的验证,比如采购单还在被合同contact引用,则不允许删除
public override void ValidateEntityBeforeDelete(IEntityCore involvedEntity)
{
base.ValidateEntityBeforeDelete(involvedEntity);
SalesOrderHeaderEntity salesOrder = (SalesOrderHeaderEntity)involvedEntity;
if (salesOrder.TotalDue != 0)
throw new Exception("Total due zero not allow for this period");
}
保存采购单前的验证,常常是验证必须输入值的字段
public override void ValidateEntityBeforeSave(IEntityCore involvedEntity)
{
base.ValidateEntityBeforeSave(involvedEntity);
SalesOrderHeaderEntity salesOrder = (SalesOrderHeaderEntity)involvedEntity;
if(salesOrder.TaxAmt>1000)
throw new Exception("unable to deal with tax more than 1000");
}
采购单的属性值发生改变时,应用此处的验证,比如,当获取截止日期后,要验证它不能小于当前日期
public override bool ValidateFieldValue(IEntityCore involvedEntity, int fieldIndex, object value)
{
bool result = base.ValidateFieldValue(involvedEntity, fieldIndex, value);
if (!result)
return false;
SalesOrderHeaderEntity salesOrder = (SalesOrderHeaderEntity)involvedEntity;
switch ((SalesOrderHeaderFieldIndex)fieldIndex)
{
case SalesOrderHeaderFieldIndex.DueDate:
return ValidateDueDate(salesOrder, (DateTime)value);
}
return true;
}
private bool ValidateDueDate(SalesOrderHeaderEntity salesOrder, DateTime value)
{
if(value.CompareTo(DateTime.Now) < 0)
throw new Exception("Due date cannot be less than today");
return true;
}
}
protected override void OnInitialized()
{
base.OnInitialized();
//Assign validator
this.Validator =new SalesOrderHeaderValidator();
}
[TestMethod]
public void TestDeleteSalesOrderHeader()
{
DataAccessAdapter adapter = new DataAccessAdapter(ConnectionString);
SalesOrderHeaderEntity salesOrder = new SalesOrderHeaderEntity(43659);
adapter.DeleteEntity(salesOrder);
}
进入DataAccessAdapterBase的方法
public bool DeleteEntity(IEntity2 entityToDelete)
{
return DeleteEntity(entityToDelete, null);
}
调用它的重载overload方法
public virtual bool DeleteEntity(IEntity2 entityToDelete, IPredicateExpression deleteRestriction)
{
EntityBase2 entityToDeleteAsEntityBase2 = (EntityBase2)entityToDelete;
entityToDeleteAsEntityBase2.CallValidateEntityBeforeDelete();
}
进入EntityBase2的CallValidateEntityBeforeDelete
internal void CallValidateEntityBeforeDelete()
{
OnValidateEntityBeforeDelete();
}
继续进入OnValidateEntityBeforeDelete方法
protected virtual void OnValidateEntityBeforeDelete()
{
if( _validator != null )
{
_validator.ValidateEntityBeforeDelete( this );
}
}
至此就进入到了我在文章开头写的SalesOrderHeaderValidator的ValidateEntityBeforeDelete方法
再来看一下ValidatorBase 中的虚拟方法ValidateEntityBeforeDelete
[Serializable]
public abstract class ValidatorBase : IValidator
{
public virtual void ValidateEntityBeforeDelete( IEntityCore involvedEntity )
{
// nop
}
}
SalesOrderHeaderEntity salesOrder = new SalesOrderHeaderEntity(2068);
salesOrder.DueDate = DateTime.Now.AddDays(-1); //这里设置DueDate 的值为昨天,违反了业务规则
来追踪它的堆栈,进入DueDate属性的set方法
public virtual System.DateTime DueDate
{
set { SetValue((int)SalesOrderHeaderFieldIndex.DueDate, value); }
}
进入EntityBase2的SetValue方法
protected bool SetValue(int fieldIndex, object value)
{
return SetValue(fieldIndex, value, true);
}
同名的重载方法
protected bool SetValue(int fieldIndex, object value, bool performDesyncForFKFields)
{
// set value is not the same as the value to set, proceed
if(ValidateValue(fieldToSet, ref valueToSet, fieldIndex))
进入ValidateValue方法
private bool ValidateValue(IFieldInfo fieldToValidate, ref object value, int fieldIndex)
{
// perform custom validation.
validationResult = (OnValidateFieldValue(fieldIndex, value));
}
流程进入OnValidateFieldValue方法
protected virtual bool OnValidateFieldValue( int fieldIndex, object value )
{
bool returnValue = true;
if( _validator != null )
{
returnValue = _validator.ValidateFieldValue(this, fieldIndex, value );
}
return returnValue;
}
请注意看这一句returnValue = _validator.ValidateFieldValue(this, fieldIndex, value ),它会进入我在开头重写的ValidateFieldValue的方法里面,最后就是进入自定义的方法ValidateDueDate
![](http://images.cnblogs.com/cnblogs_com/JamesLi2015/201108/201108290937574533.png)
这就是验证的完整堆栈流程。
常见的三种验证:
1)保存之前的验证,重写ValidateEntityBeforeSave
2) 删除前的验证,重写ValidateEntityBeforeDelete
3) 属性获取值之后的验证,重写ValidateFieldValue
先讲解一个基本的模式,基类中的设计virtual方法,派生中中override,我们在运行时,会调用实际类型的方法
public class A
{
public virtual Do() { }
}
public class B: A
{
public override Do() { }
}
当以这种方法调用时
A obj=new B():
obj.Do();
它会根据obj的实际类型,调用对应的方法
验证代码的书写
[Serializable]public partial class SalesOrderHeaderValidator : ValidatorBase
{
// __LLBLGENPRO_USER_CODE_REGION_START ValidationCode
删除采购单前的验证,比如采购单还在被合同contact引用,则不允许删除
public override void ValidateEntityBeforeDelete(IEntityCore involvedEntity)
{
base.ValidateEntityBeforeDelete(involvedEntity);
SalesOrderHeaderEntity salesOrder = (SalesOrderHeaderEntity)involvedEntity;
if (salesOrder.TotalDue != 0)
throw new Exception("Total due zero not allow for this period");
}
保存采购单前的验证,常常是验证必须输入值的字段
public override void ValidateEntityBeforeSave(IEntityCore involvedEntity)
{
base.ValidateEntityBeforeSave(involvedEntity);
SalesOrderHeaderEntity salesOrder = (SalesOrderHeaderEntity)involvedEntity;
if(salesOrder.TaxAmt>1000)
throw new Exception("unable to deal with tax more than 1000");
}
采购单的属性值发生改变时,应用此处的验证,比如,当获取截止日期后,要验证它不能小于当前日期
public override bool ValidateFieldValue(IEntityCore involvedEntity, int fieldIndex, object value)
{
bool result = base.ValidateFieldValue(involvedEntity, fieldIndex, value);
if (!result)
return false;
SalesOrderHeaderEntity salesOrder = (SalesOrderHeaderEntity)involvedEntity;
switch ((SalesOrderHeaderFieldIndex)fieldIndex)
{
case SalesOrderHeaderFieldIndex.DueDate:
return ValidateDueDate(salesOrder, (DateTime)value);
}
return true;
}
private bool ValidateDueDate(SalesOrderHeaderEntity salesOrder, DateTime value)
{
if(value.CompareTo(DateTime.Now) < 0)
throw new Exception("Due date cannot be less than today");
return true;
}
}
挂接到验证代码到实体中
重写OnInitialized方法,给Validator 属性指定验证器protected override void OnInitialized()
{
base.OnInitialized();
//Assign validator
this.Validator =new SalesOrderHeaderValidator();
}
追踪删除采购单的堆栈
先设计一个删除的采购单的测试方法[TestMethod]
public void TestDeleteSalesOrderHeader()
{
DataAccessAdapter adapter = new DataAccessAdapter(ConnectionString);
SalesOrderHeaderEntity salesOrder = new SalesOrderHeaderEntity(43659);
adapter.DeleteEntity(salesOrder);
}
进入DataAccessAdapterBase的方法
public bool DeleteEntity(IEntity2 entityToDelete)
{
return DeleteEntity(entityToDelete, null);
}
调用它的重载overload方法
public virtual bool DeleteEntity(IEntity2 entityToDelete, IPredicateExpression deleteRestriction)
{
EntityBase2 entityToDeleteAsEntityBase2 = (EntityBase2)entityToDelete;
entityToDeleteAsEntityBase2.CallValidateEntityBeforeDelete();
}
进入EntityBase2的CallValidateEntityBeforeDelete
internal void CallValidateEntityBeforeDelete()
{
OnValidateEntityBeforeDelete();
}
继续进入OnValidateEntityBeforeDelete方法
protected virtual void OnValidateEntityBeforeDelete()
{
if( _validator != null )
{
_validator.ValidateEntityBeforeDelete( this );
}
}
至此就进入到了我在文章开头写的SalesOrderHeaderValidator的ValidateEntityBeforeDelete方法
再来看一下ValidatorBase 中的虚拟方法ValidateEntityBeforeDelete
[Serializable]
public abstract class ValidatorBase : IValidator
{
public virtual void ValidateEntityBeforeDelete( IEntityCore involvedEntity )
{
// nop
}
}
验证属性值
再来看属性设置时的验证,这种验证方法可以验证程序对采购单的任何属性的复制行为。比如,业务规则是,任何时间,采购单的截止日期都不能小于输入采购单的当天,代码如下,SalesOrderHeaderEntity salesOrder = new SalesOrderHeaderEntity(2068);
salesOrder.DueDate = DateTime.Now.AddDays(-1); //这里设置DueDate 的值为昨天,违反了业务规则
来追踪它的堆栈,进入DueDate属性的set方法
public virtual System.DateTime DueDate
{
set { SetValue((int)SalesOrderHeaderFieldIndex.DueDate, value); }
}
进入EntityBase2的SetValue方法
protected bool SetValue(int fieldIndex, object value)
{
return SetValue(fieldIndex, value, true);
}
同名的重载方法
protected bool SetValue(int fieldIndex, object value, bool performDesyncForFKFields)
{
// set value is not the same as the value to set, proceed
if(ValidateValue(fieldToSet, ref valueToSet, fieldIndex))
进入ValidateValue方法
private bool ValidateValue(IFieldInfo fieldToValidate, ref object value, int fieldIndex)
{
// perform custom validation.
validationResult = (OnValidateFieldValue(fieldIndex, value));
}
流程进入OnValidateFieldValue方法
protected virtual bool OnValidateFieldValue( int fieldIndex, object value )
{
bool returnValue = true;
if( _validator != null )
{
returnValue = _validator.ValidateFieldValue(this, fieldIndex, value );
}
return returnValue;
}
请注意看这一句returnValue = _validator.ValidateFieldValue(this, fieldIndex, value ),它会进入我在开头重写的ValidateFieldValue的方法里面,最后就是进入自定义的方法ValidateDueDate
![](http://images.cnblogs.com/cnblogs_com/JamesLi2015/201108/201108290937574533.png)
这就是验证的完整堆栈流程。
相关文章推荐
- LLBL Gen 3.x 源代码追踪与解析 Type Converter 类型转换器
- LLBL Gen 3.x 源代码追踪与解析 认识框架结构
- LLBL Gen 3.x 源代码追踪与解析 认识框架结构
- LLBL Gen 3.x 源代码追踪与解析 查询命令的追踪
- LLBL Gen 3.x 源代码追踪与解析 存储过程的执行
- 匿名函数验证用户代码实例解析Ajax技术原理
- Zookeeper系列(十六)Zookeeper原理解析之选举之选举流程
- RocketMQ原理解析-producer 1.启动流程
- https原理:证书传递、验证和数据加密、解密过程解析
- Asp.net中基于Forms验证的角色验证授权[原理及流程]
- https原理:证书传递、验证和数据加密、解密过程解析
- 秋色园QBlog技术原理解析:认识整站处理流程(二)
- https原理:证书传递、验证和数据加密、解密过程解析
- SQL语句执行流程与顺序原理解析
- https原理:证书传递、验证和数据加密、解密过程解析
- ATMS工作流程原理解析
- http访问解析流程原理
- Zookeeper系列(二十三)Zookeeper原理解析之选举流程
- Android View体系(八)从源代码解析View的layout和draw流程
- zabbix身份验证流程解析&绕过身份验证的方法