本系列主旨是记录本人在项目开发和语言的学习中总结的小技巧,自知能力有限,不足登大雅之堂,但本着学习和交流的态度,希望各位同仁给与批评和指正。
在此不胜感激!!
转载请注明出处:http://suchenge.cnblogs.com
数据交互是WEB交互的核心功能,用户在Web页面的表单中提交数据,程序接受数据后进行相应的逻辑运算后将数据写入数据库中,在这样的应用中无论是考虑到应用系统的安全还是用户数据的完整,我们都将对用户提交的数据信息进行相应的验证。
比如一个用户注册的交互应用:
一般会在Model层建立一个注册类
public class Register
{
public string Account { get ; set ; }
public string Password { get ; set ; }
public string Email { get ; set ; }
}
在UI层将页面提交来的数据对应赋予Register类实例化后的对象的属性,之后将对象传递给BLL层进行数据库的操作
Register register = new Register();
register.Account = HttpContext.Current.Request[ " txtAccount " ].Trim();
register.Password = HttpContext.Current.Request[ " txtPassword " ].Trim();
register.Email = HttpContext.Current.Request[ " txtEmail " ].Trim();
在这里,我们暂不谈数据的安全性,只讨论数据的完整性,在这样的应用中Register类中的Account和Password属性,作为用户今后登录的重要依据,是必填的,通常情况下,我们会在将参数赋值给对象属性前先进行判断是否为空的操作
string account = string .Empty;
if ( ! string .IsNullOrEmpty(HttpContext.Current.Request[ " txtAccount " ]))
{
account = HttpContext.Current.Request[ " txtAccount " ].Trim();
}
register.Account = account;
但是,当一个需要赋值的对象的属性非常多时,我们的判断工作将是灾难性的。
还好,.Net为我们提供了Attribute类(字面上解释应该叫做“属性”,但我叫它“修饰”,因为它和类的“Property”同名)
我们可以通过建立一个验证用的Attribute对象VerifyAttribute,并给Register类的属性加上VerifyAttribute型的修饰,记录下属性的规则,比如类型、是否可以为空,最大值以及最小值等,并建立一个通过对象属性修饰(Attribute)验证对象属性规则的类Verify,在Register对象个属性赋值好后,通过Verify的验证过程,返回验证信息。
/// <summary>
/// 实体属性验证设置特性对象
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = false , AllowMultiple = true )]
public abstract class VerifyAttribute : Attribute
{
/// <summary>
/// 说明
/// </summary>
protected string _Explain;
/// <summary>
/// 是否可以为空
/// </summary>
protected bool _NotNull;
/// <summary>
/// 正则表达式
/// </summary>
protected string _RegexExpressions;
/// <summary>
/// 获取说明
/// </summary>
public string Explain
{
get { return _Explain; }
}
/// <summary>
/// 获取是否可以为空值
/// </summary>
public bool NotNULL
{
get { return _NotNull; }
}
/// <summary>
/// 获取验证正则表达式
/// </summary>
public string RegexExpressions
{
get { return _RegexExpressions; }
}
/// <summary>
/// 为内部字段赋值
/// </summary>
/// <param name="explain"> 属性说明 </param>
/// <param name="notnull"> 是否不可为空 </param>
/// <param name="regexexpressions"> 正则表达式,为空不验证 </param>
protected void GetParam( string explain, bool notnull, string regexexpressions)
{
_Explain = explain;
_NotNull = notnull;
_RegexExpressions = regexexpressions;
}
}
/// <summary>
/// 实体字符类型属性验证设置特性对象
/// </summary>
public class VerifyString : VerifyAttribute
{
/// <summary>
/// 最大长度
/// </summary>
protected int _MaxLength;
/// <summary>
/// 获取最大长度
/// </summary>
public int MaxLength
{
get { return _MaxLength; }
}
/// <summary>
/// 为实体字符类型属性设置验证特性
/// </summary>
/// <param name="explain"> 属性说明 </param>
/// <param name="notnull"> 是否可以为空 </param>
/// <param name="maxlength"> 属性值最大长度 </param>
public VerifyString( string explain, bool notnull, int maxlength)
{
_MaxLength = maxlength;
GetParam(explain, notnull, "" );
}
/// <summary>
/// 为实体字符类型属性设置验证特性
/// </summary>
/// <param name="explain"> 属性说明 </param>
/// <param name="notnull"> 是否可以为空 </param>
public VerifyString( string explain, bool notnull) {
_MaxLength = 0 ;
GetParam(explain, notnull, "" );
}
/// <summary>
/// 为实体字符类型属性设置验证特性
/// </summary>
/// <param name="explain"> 属性说明 </param>
/// <param name="notnull"> 是否可以为空 </param>
/// <param name="maxlength"> 属性值最大长度 </param>
/// <param name="regexexpressions"> 正则表达式,为空不验证 </param>
public VerifyString( string explain, bool notnull, int maxlength, string regexexpressions)
{
_MaxLength = maxlength;
GetParam(explain, notnull, regexexpressions);
}
}
上面两个类VerifyString继承自VerifyAttribute类,主要是用作对String类型的属性的修饰,其中加入了可通过正则表达式进行验证的功能。
建立实现验证过程的对象
/// <summary>
/// 实例属性数据格式验证对象
/// </summary>
public class Verify {
/// <summary>
/// 验证属性数据格式,并返回验证结果
/// </summary>
/// <typeparam name="T"> 必须继承自BaseObject </typeparam>
/// <param name="t"> 要验证的实例 </param>
/// <param name="separator"> 分割验证结果的自定义分隔符 </param>
/// <returns> 验证结果 </returns>
public static string VerificationDataToString < T > (T t, string separator)
{
System.Type type = t.GetType();
StringBuilder strTmp = new StringBuilder();
foreach (PropertyInfo P in type.GetProperties())
{
foreach (Attribute attr in P.GetCustomAttributes( true ))
{
VerifyAttribute vattr = attr as VerifyAttribute;
string typename = vattr.GetType().ToString();
typename = typename.Substring(typename.LastIndexOf( " . " ) + 1 );
object pv = P.GetValue(t, null );
if (vattr.NotNULL)
{
if (pv == null || pv.ToString() == "" )
{
strTmp.AppendFormat( " {0}不得为空{1} " , vattr.Explain, separator);
}
}
switch (typename)
{
case " VerifyString " :
VerifyString vattrs = (VerifyString) vattr;
if (pv != null )
{
if (vattrs.MaxLength > 0 )
{
if (pv.ToString().Length > vattrs.MaxLength)
{
strTmp.AppendFormat( " {0}长度不得超过{1},现在是{2}{3} " ,
vattrs.Explain,
vattrs.MaxLength,
pv.ToString().Length,
separator);
}
}
}
break ;
case " VerifyDate " :
break ;
case " VerifyNumber " :
break ;
}
if (vattr.RegexExpressions != "" )
{
if (pv != null )
{
if ( ! TestRegex(pv.ToString(), vattr.RegexExpressions))
strTmp.AppendFormat( " {0}不符合格式要求{1} " , vattr.Explain, separator);
}
}
}
}
if (strTmp.ToString().Length <= 0 ) return "" ;
else return strTmp.ToString().Substring( 0 , strTmp.ToString().LastIndexOf(separator));
}
/// <summary>
/// 通过正则检查字符中是否存在指定字符
/// </summary>
/// <param name="value"> 要检查的字符串 </param>
/// <param name="regex"> 正则表达式 </param>
/// <returns> 真or假 </returns>
private static bool TestRegex( string value, string regex)
{
return Regex.IsMatch(value, regex);
}
}
函数VerificationData(),接受一个泛型对象,并遍历对象的属性以及属性的修饰(Attribute),取出属性的值后根据修饰描述的规则进行验证判断,最后返回验证结果。
这样,我们修改之前的Register类,为其属性加上VerifyAttribute验证规则修饰
public class Register
{
// 必填,长度不得超过50字符,启用正则验证规则"^[\w|@|.|_]{2,20}$"
[VerifyString( " 账户 " , true , 50 , RegularExpression.Account)]
public string Account { get ; set ; }
// 必填,长度不得超过50字符,启用正则验证规则"^[a-zA-Z0-9]{6,20}$"
[VerifyString( " 密码 " , true , 50 , RegularExpression.Password)]
public string Password { get ; set ; }
// 必填,长度不得超过150字符,启用正则验证规则"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"
[VerifyString( " 邮箱 " , true , 150 , RegularExpression.Email)]
public string Email { get ; set ; }
}
在实际应用中我们通过Verify对象的VerificationData函数返回验证结果
string account = "" ;
string password = " $%123 " ;
string email = " ffssfs@fdfds " ;
string err = string .Empty;
Register register = new Register();
register.Account = account;
register.Password = password;
register.Email = email;
err = Verify.VerificationData < Register > (register, " <br/> " );
if (err == string .Empty)
{
// 验证通过
}
else
{
HttpContext.Current.Response.Write(err);
err应该返回:“账号不能为空 <br/>请正确填写账号<br/>请正确填写密码<br/> 请正确填写邮箱”
}
代码是从之前的项目中拷贝过来的,没有再次经过测试,如果有问题请与我联系,非常感谢!!