用来验证字符串的规则引擎

规则引擎:用来验证字符串是否符合预配置的规则,可以通过配置文件动态定义不同的字符串验证条件

规则引擎主代码(RuleEngine.cs )
using System;
using System.Text.Regulars;
namespace Rule
{
    
/// <summary>
    
/// Rule Engine 
    
/// </summary>
    public class RuleEngine
    {
        
/// <summary>
        
/// If you want the RuleEngine throw an exception when checking rule failed,
        
/// please set this value to true
        
/// </summary>
        private static bool _throwException = false;
        
public static bool ThrowExceptionCodeDirectly
        {
            
set
            {
                _throwException 
= value;
            }
            
get
            {
                
return _throwException;
            }
        }
        
/// <summary>
        
/// Check a group of rules by setId
        
/// </summary>
        
/// <param name="setId">the set id which you defined in configuration file</param>
        
/// <param name="value">the value you want check</param>
        
/// <returns>checking result</returns>
        public static bool Process(string setId, string value)
        {
            
bool result = false;
            RuleSet ruleSet 
= ConfigCache.GetRuleSet(setId);
            
if (ruleSet!=null && ruleSet.RuleIdList!=null)
            {
                Rule rule;
                
for (int i = 0; i < ruleSet.RuleIdList.Length; i++)
                {
                    rule 
= ConfigCache.GetRule(ruleSet.RuleIdList[i]);
                    
if (!CheckRule(rule, value))
                    {
                        
if (_throwException)
                        {
                            
throw new Exception(rule.ErrorCode);
                        }
                        
return false;
                    }
                }
                result 
= true;
            }
            
return result;
        }
        
private static bool CheckRule(Rule rule, string value)
        {
            
bool result = false;
            
if (rule!=null)
            {
                
switch (rule.Type)
                {
                    
case RuleType.IsNullOrEmpty:
                        result 
= !String.IsNullOrEmpty(value);
                        
break;
                    
case RuleType.MinLength:
                        
if (!String.IsNullOrEmpty(value) && !String.IsNullOrEmpty(rule.Value))
                        {
                            
int len = Int32.Parse(rule.Value);
                            result 
= (value.Length>=len);
                        }
                        
break;
                    
case RuleType.MaxLength:
                        
if (!String.IsNullOrEmpty(value) && !String.IsNullOrEmpty(rule.Value))
                        {
                            
int len = Int32.Parse(rule.Value);
                            result 
= (value.Length <= len);
                        }
                        
break;
                    
case RuleType.Pattern:
                        
if (!String.IsNullOrEmpty(value) && !String.IsNullOrEmpty(rule.Value))
                        {
                            Regex reg 
= new Regex(rule.Value);
                            result 
= reg.IsMatch(value);
                        }
                        
break;
                    
case RuleType.HasSpace:
                        
if (!String.IsNullOrEmpty(value))
                        {
                            result 
= !value.Contains(" ");
                        }
                        
break;
                    
default:
                        
break;
                }
            }
            
return result;
        }
    }
    
/// <summary>
    
/// Rule Type Enumeration
    
/// Note: each int value should match with the rule type definition in config file
    
/// </summary>
    public enum RuleType
    {
        IsNullOrEmpty 
= 1,
        MinLength 
= 2,
        MaxLength 
= 3,
        Pattern 
= 4,
        HasSpace 
= 5
    }
    
/// <summary>
    
/// Rule Class
    
/// </summary>
    public class Rule
    {
        
/// <summary>
        
/// Rule ID
        
/// </summary>
        private string _id;
        
public string ID
        {
            
set
            {
                _id 
= value;
            }
            
get
            {
                
return _id;
            }
        }
        
/// <summary>
        
/// Rule Name
        
/// </summary>
        private string _name;
        
public string Name
        {
            
set
            {
                _name 
= value;
            }
            
get
            {
                
return _name;
            }
        }
        
/// <summary>
        
/// Rule Type
        
/// </summary>
        private RuleType _type;
        
public RuleType Type
        {
            
set
            {
                _type 
= value;
            }
            
get
            {
                
return _type;
            }
        }
        
/// <summary>
        
/// Set true to reverse a rule result
        
/// </summary>
        private bool _isNot = false;
        
public bool IsNot
        {
            
set
            {
                _isNot 
= value;
            }
            
get
            {
                
return _isNot;
            }
        }
        
/// <summary>
        
/// ErrorCode
        
/// </summary>
        private string _errorCode;
        
public string ErrorCode
        {
            
set
            {
                _errorCode 
= value;
            }
            
get
            {
                
return _errorCode;
            }
        }
        
/// <summary>
        
/// Value data of config file
        
/// </summary>
        private string _value;
        
public string Value
        {
            
set
            {
                _value 
= value;
            }
            
get
            {
                
return _value;
            }
        }
    }
    
/// <summary>
    
/// A group of rules
    
/// </summary>
    public class RuleSet
    {
        
/// <summary>
        
/// Set Id
        
/// </summary>
        private string _setId;
        
public string SetId
        {
            
set
            {
                _setId 
= value;
            }
            
get
            {
                
return _setId;
            }
        }
        
/// <summary>
        
/// Rule Id List
        
/// </summary>
        private string[] _ruleIdList;
        
public string[] RuleIdList
        {
            
set
            {
                _ruleIdList 
= value;
            }
            
get
            {
                
return _ruleIdList;
            }
        }
    }
}
配置文件(RuleEngine.config )
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<defaultErrorCode>500</defaultErrorCode>
  
<!--Rule Type Definition: Fixed, Do not change-->
  
<ruleType>
    
<type id="1" name="IsNullOrEmpty"></type>
    
<type id="2" name="MinLength"></type>
    
<type id="3" name="MaxLength"></type>
    
<type id="4" name="Pattern"></type>
    
<type id="5" name="HasSpace"></type>
  
</ruleType>
  
<!--Rules Configuration: id and type are required attributes-->
  
<rules>
    
<!--Email Validation-->
    
<rule id="1" name="EmailNotEmpty" type="1" errorCode="-712"></rule>
    
<rule id="2" name="EmailPattern" type="4" errorCode="-710" value="^([\\w-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([\\w-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$"></rule>
    
<!--UserName Validation-->
    
<rule id="3" name="UserNameNotEmpty" type="1" errorCode="-778"></rule>
    
<rule id="4" name="UserNamePattern" type="4" errorCode="-707" value="^[-._a-zA-Z0-9]+$"></rule>
    
<rule id="5" name="MinUserNameLength" type="2" errorCode="-706" value="4"></rule>
    
<rule id="6" name="MaxUserNameLength" type="3" errorCode="-705" value="20"></rule>
    
<!--Password Validation-->
    
<rule id="7" name="UserPasswordNotEmpty" type="1" errorCode="-714"></rule>
    
<rule id="8" name="UserPasswordSpace" type="5" errorCode="-717"></rule>
    
<rule id="9" name="UserPasswordPattern" type="4" errorCode="-748" value="^((\\d+)|([!-/:-@\\[-`{-~]+)|(\\d+[a-zA-Z]+|[a-zA-Z]+\\d+)([\\da-zA-A]*)|([!-/:-@\\[-`{-~]+[a-zA-Z]+|[a-zA-Z]+[!-/:-@\\[-`{-~]+)([a-zA-Z!-/:-@\\[-`{-~]*)|(\\d+[a-zA-Z]+[!-/:-@\\[-`{-~]+|\\d+[!-/:-@\\[-`{-~]+[a-zA-Z]+|[a-zA-Z]+\\d+[!-/:-@\\[-`{-~]+|[a-zA-Z]+[!-/:-@\\[-`{-~]+\\d+|[!-/:-@\\[-`{-~]+[a-zA-Z]+\\d+|[!-/:-@\\[-`{-~]+\\d+[a-zA-Z]+)([\\da-zA-Z!-/:-@\\[-`{-~]*))$"></rule>
    
<rule id="10" name="MinUserPasswordLength" type="2" errorCode="-715" value="6"></rule>
    
<rule id="11" name="MaxUserPasswordLength" type="3" errorCode="-716" value="16"></rule>
    
<!--User Profile Validation-->
    
<rule id="12" name="UserDobNotEmpty" type="1" errorCode="-720"></rule>
    
<rule id="13" name="UserDobPattern" type="4" errorCode="-721" value="^[12]\\d{3}-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2]\\d|3[01])$"></rule>
    
<rule id="14" name="UserCountryNotEmpty" type="1" errorCode="-724"></rule>
    
<rule id="15" name="UserLanguageNotEmpty" type="1" errorCode="-727"></rule>
    
<rule id="16" name="UserTosVersionNotEmpty" type="1" errorCode="-729"></rule>
    
<rule id="17" name="UserStatusNotEmpty" type="1" errorCode="-731"></rule>
    
<!--Persona Profile Validation-->
    
<rule id="18" name="PersonaDisplayNameNotEmpty" type="1" errorCode="-761"></rule>
    
<rule id="19" name="MinPersonaDisplayNameLength" type="1" errorCode="-764"></rule>
    
<rule id="20" name="MaxPersonaDisplayNameLength" type="1" errorCode="-763"></rule>
    
<rule id="21" name="PersonaDisplayNamePattern" type="4" errorCode="-1803" value="^[-._a-zA-Z0-9]+$"></rule>
    
<rule id="22" name="PersonaStatusNotEmpty" type="1" errorCode="-766"></rule>
  
</rules>
  
<!--Rule Set Configuration: do not add comments in ruleSets node-->
  
<ruleSets>
    
<set id="userEmail">
      
<rule id="1"></rule>
      
<rule id="2"></rule>
    
</set>
    
<set id="userName">
      
<rule id="3"></rule>
      
<rule id="4"></rule>
      
<rule id="5"></rule>
      
<rule id="6"></rule>
    
</set>
    
<set id="userPassword">
      
<rule id="7"></rule>
      
<rule id="8"></rule>
      
<rule id="9"></rule>
      
<rule id="10"></rule>
      
<rule id="11"></rule>
    
</set>
    
<set id="userDob">
      
<rule id="12"></rule>
      
<rule id="13"></rule>
    
</set>
    
<set id="userCountry">
      
<rule id="14"></rule>
    
</set>
    
<set id="userLanguage">
      
<rule id="15"></rule>
    
</set>
    
<set id="userTosVersion">
      
<rule id="16"></rule>
    
</set>
    
<set id="userStatus">
      
<rule id="17"></rule>
    
</set>
    
<set id="personaName">
      
<rule id="18"></rule>
      
<rule id="19"></rule>
      
<rule id="20"></rule>
      
<rule id="21"></rule>
    
</set>
    
<set id="personaStatus">
      
<rule id="22"></rule>
    
</set>
  
</ruleSets>
</configuration>
配置信息缓存类(RuleEngine_ConfigCache.cs)
using System;
using System.IO;
using System.Xml;
using EA.Common.Util;
namespace Rule
{
    
/// <summary>
    
/// Config Cache Class used for cache config file
    
/// </summary>
    public class ConfigCache
    {
        
/// <summary>
        
/// Config Name: this value is defined in Web Config file, used for define RuleEngine configue file name
        
/// </summary>
        private const string _configName = "RuleEngine";
        
/// <summary>
        
/// Full File Name
        
/// </summary>
        private static string _fullFileName = "";
        
/// <summary>
        
/// Config file root node name
        
/// </summary>
        private const string _root = "configuration";
        
/// <summary>
        
/// FileInfo used for check file change
        
/// </summary>
        private static FileInfo _fileInfo;
        
/// <summary>
        
/// Last check
        
/// </summary>
        private static DateTime _lastCheck;
        
/// <summary>
        
/// last modify time of config file
        
/// </summary>
        private static DateTime _lastModified;
        
        
/// <summary>
        
/// Default Error Code will throw when checking a rule fail and set ThrowExceptionCodeDirectly to true
        
/// </summary>
        private static string _defaultErrorCode;
        
public static string DefaultErrorCode
        {
            
set
            {
                _defaultErrorCode 
= value;
            }
            
get
            {
                
return _defaultErrorCode;
            }
        }
        
/// <summary>
        
/// Rule Array
        
/// </summary>
        private static Rule[] _ruleArray;
        
public static Rule[] RuleArray
        {
            
set
            {
                _ruleArray 
= value;
            }
            
get
            {
                
return _ruleArray;
            }
        }
        
/// <summary>
        
/// Rule Set Array
        
/// </summary>
        private static RuleSet[] _ruleSetArray;
        
public static RuleSet[] RuleSetArray
        {
            
set
            {
                _ruleSetArray 
= value;
            }
            
get
            {
                
return _ruleSetArray;
            }
        }
        
/// <summary>
        
/// Static Constructor
        
/// </summary>
        static ConfigCache()
        {
            
string fileName = ServiceConfiguration.GetInstance().GetAppSetting(_configName);
            
string filePath = AppDomain.CurrentDomain.BaseDirectory + "\\";
            _fullFileName 
= filePath + fileName;
            _fileInfo 
= new FileInfo(_fullFileName);
            Load();
            _lastModified 
= GetLastModified();
            _lastCheck 
= DateTime.Now;
        }
        
/// <summary>
        
/// Load config data from xml file
        
/// </summary>
        private static void Load()
        {
            XmlDocument doc 
= new XmlDocument();
            doc.Load(_fullFileName);
            
if (doc != null)
            {
                
//Load DefaultErrorCode
                XmlNode ruleNode = doc.SelectSingleNode("/" + _root + "/defaultErrorCode");
                
if (ruleNode!=null)
                {
                    _defaultErrorCode 
= ruleNode.InnerText;
                }
                
//Load Rule List
                _ruleArray = GetRuleList(doc);
                
//Load Rule Set List
                _ruleSetArray = GetRuleSetList(doc);
            }
        }
        
/// <summary>
        
/// Get arrtibute name of XmlNode object
        
/// </summary>
        
/// <param name="attName"></param>
        
/// <returns></returns>
        private static string GetAttribute(XmlNode node, string attName)
        {
            
if (node != null && node.Attributes[attName]!=null)
            {
                
return node.Attributes[attName].Value;
            }
            
return null;
        }
        
/// <summary>
        
/// Get Rule List
        
/// </summary>
        
/// <param name="doc"></param>
        
/// <returns></returns>
        private static Rule[] GetRuleList(XmlDocument doc)
        {
            Rule[] array 
= null;
            XmlNode ruleNode 
= doc.SelectSingleNode("/" + _root + "/rules");
            
if (ruleNode.ChildNodes.Count > 0)
            {
                array 
= new Rule[ruleNode.ChildNodes.Count];
                Rule rule;
                
int index = 0;
                
for (int i = 0; i < ruleNode.ChildNodes.Count; i++)
                {
                    
//skip comment
                    if (ruleNode.ChildNodes[i].NodeType == XmlNodeType.Comment)
                    {
                        
continue;
                    }
                    rule 
= new Rule();
                    rule.ID 
= GetAttribute(ruleNode.ChildNodes[i],"id");
                    rule.Name 
= GetAttribute(ruleNode.ChildNodes[i],"name");
                    
string strType = GetAttribute(ruleNode.ChildNodes[i],"type");
                    
if (!String.IsNullOrEmpty(strType))
                    {
                        rule.Type 
= (RuleType)Enum.Parse(typeof(RuleType), strType);
                    }
                    
string strIsNot = GetAttribute(ruleNode.ChildNodes[i],"isNot");
                    
if (!String.IsNullOrEmpty(strIsNot))
                    {
                        rule.IsNot 
= Boolean.Parse(strIsNot);
                    }
                    rule.ErrorCode 
= GetAttribute(ruleNode.ChildNodes[i],"errorCode");
                    rule.Value 
= GetAttribute(ruleNode.ChildNodes[i], "value");
                    
                    array[index] 
= rule;
                    index
++;
                }
            }
            
            
return array;
        }
        
/// <summary>
        
/// Get Rule Set List
        
/// </summary>
        
/// <param name="doc"></param>
        
/// <returns></returns>
        private static RuleSet[] GetRuleSetList(XmlDocument doc)
        {
            RuleSet[] setArray 
= null;
            XmlNode setNode 
= doc.SelectSingleNode("/" + _root + "/ruleSets");
            
if (setNode.ChildNodes.Count > 0)
            {
                setArray 
= new RuleSet[setNode.ChildNodes.Count];
                RuleSet 
set;
                
for (int i = 0; i < setNode.ChildNodes.Count; i++)
                {
                    XmlNode ruleNode 
= setNode.ChildNodes[i];
                    
//skip comment
                    if (ruleNode.NodeType == XmlNodeType.Comment)
                    {
                        
continue;
                    }
                    
set = new RuleSet();
                    
set.SetId = GetAttribute(ruleNode,"id");
                    
if (ruleNode.ChildNodes.Count > 0)
                    {
                        
set.RuleIdList = new string[ruleNode.ChildNodes.Count];
                        
for (int j = 0; j < ruleNode.ChildNodes.Count; j++)
                        {
                            
//skip comment
                            if (ruleNode.ChildNodes[j].NodeType == XmlNodeType.Comment)
                            {
                                
continue;
                            }
                            
set.RuleIdList[j] = GetAttribute(ruleNode.ChildNodes[j],"id");
                        }
                    }
                    setArray[i] 
= set;
                }
            }
            
return setArray;
        }
        
/// <summary>
        
/// Get tule object by rule id
        
/// </summary>
        
/// <param name="ruleId"></param>
        public static Rule GetRule(string ruleId)
        {
            Rule result 
= null;
            
if (_ruleArray != null)
            {
                
for (int i = 0; i < _ruleArray.Length; i++)
                {
                    
if (_ruleArray[i].ID == ruleId)
                    {
                        result 
= _ruleArray[i];
                        
break;
                    }
                }
            }
            
return result;
        }
        
/// <summary>
        
/// Get rule set object by set id
        
/// </summary>
        
/// <param name="setId"></param>
        public static RuleSet GetRuleSet(string setId)
        {
            CheckFileChanged();
            RuleSet result 
= null;
            
if (_ruleSetArray != null)
            {
                
for (int i = 0; i < _ruleSetArray.Length; i++)
                {
                    
if (_ruleSetArray[i].SetId == setId)
                    {
                        result 
= _ruleSetArray[i];
                        
break;
                    }
                    
if (i==(_ruleSetArray.Length-1))
                    {
                        
throw new Exception("RuleEngine can't find set id:" + setId);
                    }
                }
            }
            
return result;
        }
        
/// <summary>
        
/// if config file changed, invoke this method will reload config data from disk
        
/// </summary>
        private static void CheckFileChanged()
        {
            
//Less than 10mins, do not check
            if (DateTime.Now.Subtract(_lastCheck).Minutes < 10)
            {
                
return;
            }
            DateTime check 
= GetLastModified();
            
if (_lastModified != check)
            {
                Load();
                _lastModified 
= check;
                _lastCheck 
= DateTime.Now;
            }
        }
        
/// <summary>
        
/// Get last modify time of config file
        
/// </summary>
        
/// <returns></returns>
        private static DateTime GetLastModified()
        {
            _fileInfo.Refresh();
            
return _fileInfo.LastWriteTime;
        }
    }
}
原文地址:https://www.cnblogs.com/andy65007/p/1631040.html