早上看到了利用特性(Attribute)对实体类进行验证 这篇文章,碰上刚好最近对Attribute有点兴趣,所以对作者写的利用特性(Attribute)对实体类进行验证这篇文章进行练习并且对知识点进行巩固。
自己改写的版本如下:C#4.0


namespace
ValidateDemo
{
[Flags]
public enum ValidateType
{
NotEmpty = 1 ,
MaxLength = 2 ,
MinLength = 4 ,
IsPhone = 8
}
[AttributeUsage(AttributeTargets.All,AllowMultiple = true )]
public class ValidateAttribute : Attribute
{
public ValidateAttribute(ValidateType validateType)
{
ValidateType = validateType;
}
public ValidateType ValidateType { get ; set ; }
public int MinLength { get ; set ; }
public int MaxLength { get ; set ; }
public string [] CustomArray { get ; set ; }
}
public class ValidateModel
{
/// <summary>
/// 验证类型
/// </summary>
public ValidateType Type{ get ; set ;}
/// <summary>
/// 验证函数
/// </summary>
public Func < bool > CheckFunc { get ; set ; }
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMessage { get ; set ; }
}
public class Validate
{
/// <summary>
/// 检查需要验证的函数是否通过
/// </summary>
/// <param name="checkType"> 被检查类型 </param>
/// <param name="matchType"> 需要检查的类型 </param>
/// <param name="func"> 检查函数 </param>
/// <param name="errMessage"> 错误信息 </param>
/// <returns> Emtpy 验证通过,否则返回错误信息 </returns>
private static string CheckValidate(ValidateType checkType,ValidateType matchType,Func < bool > func, string errMessage)
{
if (checkType.HasFlag(matchType))
{
if (func())
{
return errMessage;
}
}
return String.Empty;
}
/// <summary>
/// 检查对象是否通过验证
/// </summary>
/// <param name="entityObject"> 需要检查的对象 </param>
/// <param name="errMessage"> 返回错误信息 </param>
/// <returns> true:通过,false:失败 </returns>
public static bool GetValidateResult( object entityObject, out string errMessage)
{
Type type = entityObject.GetType();
PropertyInfo[] properties = type.GetProperties();
string validateResult = string .Empty;
errMessage = string .Empty;
foreach (PropertyInfo property in properties)
{
object [] validateContent = property.GetCustomAttributes( typeof (ValidateAttribute), true );
if (validateContent != null )
{
object value = property.GetValue(entityObject, null );
foreach (ValidateAttribute validateAttribute in validateContent)
{
IList < ValidateModel > condition = new List < ValidateModel > ();
// 需要什么验证,在这里添加
condition.Add( new ValidateModel { Type = ValidateType.NotEmpty, CheckFunc = () => { return (value == null || value.ToString().Length < 1 ); }, ErrorMessage = String.Format( " 元素{0}不能为空。 " , property.Name) });
condition.Add( new ValidateModel { Type = ValidateType.MaxLength, CheckFunc = () => { return (value.ToString().Length > validateAttribute.MaxLength); }, ErrorMessage = String.Format( " 元素{0}长度不能超过{1} " , property.Name, validateAttribute.MaxLength) });
condition.Add( new ValidateModel { Type = ValidateType.MinLength, CheckFunc = () => { return (value.ToString().Length < validateAttribute.MinLength); }, ErrorMessage = String.Format( " 元素{0}长度不能小于{1} " , property.Name, validateAttribute.MinLength) });
condition.Add( new ValidateModel { Type = ValidateType.IsPhone, CheckFunc = () => { return ( ! System.Text.RegularExpressions.Regex.IsMatch(value.ToString(), @" ^\d+$ " )); }, ErrorMessage = String.Format( " 元素{0}必须是电话号码 " , property.Name) });
foreach (ValidateModel model in condition)
{
validateResult = CheckValidate(
validateAttribute.ValidateType,
model.Type,
model.CheckFunc,
model.ErrorMessage
);
if ( ! string .IsNullOrEmpty(validateResult))
{
errMessage = validateResult;
return false ;
}
}
}
}
}
return true ;
}
}
public class User
{
[Validate(ValidateType.MinLength,MinLength = 5 )]
[Validate(ValidateType.IsPhone)]
public string Password { get ; set ; }
}
class Program
{
static void Main( string [] args)
{
string msg = string .Empty;
User user = new User();
user.Password = " 31234a " ;
if (Validate.GetValidateResult(user, out msg))
{
Console.WriteLine( " 测试通过 " );
}
else
{
Console.WriteLine(msg);
}
}
}
}
{
[Flags]
public enum ValidateType
{
NotEmpty = 1 ,
MaxLength = 2 ,
MinLength = 4 ,
IsPhone = 8
}
[AttributeUsage(AttributeTargets.All,AllowMultiple = true )]
public class ValidateAttribute : Attribute
{
public ValidateAttribute(ValidateType validateType)
{
ValidateType = validateType;
}
public ValidateType ValidateType { get ; set ; }
public int MinLength { get ; set ; }
public int MaxLength { get ; set ; }
public string [] CustomArray { get ; set ; }
}
public class ValidateModel
{
/// <summary>
/// 验证类型
/// </summary>
public ValidateType Type{ get ; set ;}
/// <summary>
/// 验证函数
/// </summary>
public Func < bool > CheckFunc { get ; set ; }
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMessage { get ; set ; }
}
public class Validate
{
/// <summary>
/// 检查需要验证的函数是否通过
/// </summary>
/// <param name="checkType"> 被检查类型 </param>
/// <param name="matchType"> 需要检查的类型 </param>
/// <param name="func"> 检查函数 </param>
/// <param name="errMessage"> 错误信息 </param>
/// <returns> Emtpy 验证通过,否则返回错误信息 </returns>
private static string CheckValidate(ValidateType checkType,ValidateType matchType,Func < bool > func, string errMessage)
{
if (checkType.HasFlag(matchType))
{
if (func())
{
return errMessage;
}
}
return String.Empty;
}
/// <summary>
/// 检查对象是否通过验证
/// </summary>
/// <param name="entityObject"> 需要检查的对象 </param>
/// <param name="errMessage"> 返回错误信息 </param>
/// <returns> true:通过,false:失败 </returns>
public static bool GetValidateResult( object entityObject, out string errMessage)
{
Type type = entityObject.GetType();
PropertyInfo[] properties = type.GetProperties();
string validateResult = string .Empty;
errMessage = string .Empty;
foreach (PropertyInfo property in properties)
{
object [] validateContent = property.GetCustomAttributes( typeof (ValidateAttribute), true );
if (validateContent != null )
{
object value = property.GetValue(entityObject, null );
foreach (ValidateAttribute validateAttribute in validateContent)
{
IList < ValidateModel > condition = new List < ValidateModel > ();
// 需要什么验证,在这里添加
condition.Add( new ValidateModel { Type = ValidateType.NotEmpty, CheckFunc = () => { return (value == null || value.ToString().Length < 1 ); }, ErrorMessage = String.Format( " 元素{0}不能为空。 " , property.Name) });
condition.Add( new ValidateModel { Type = ValidateType.MaxLength, CheckFunc = () => { return (value.ToString().Length > validateAttribute.MaxLength); }, ErrorMessage = String.Format( " 元素{0}长度不能超过{1} " , property.Name, validateAttribute.MaxLength) });
condition.Add( new ValidateModel { Type = ValidateType.MinLength, CheckFunc = () => { return (value.ToString().Length < validateAttribute.MinLength); }, ErrorMessage = String.Format( " 元素{0}长度不能小于{1} " , property.Name, validateAttribute.MinLength) });
condition.Add( new ValidateModel { Type = ValidateType.IsPhone, CheckFunc = () => { return ( ! System.Text.RegularExpressions.Regex.IsMatch(value.ToString(), @" ^\d+$ " )); }, ErrorMessage = String.Format( " 元素{0}必须是电话号码 " , property.Name) });
foreach (ValidateModel model in condition)
{
validateResult = CheckValidate(
validateAttribute.ValidateType,
model.Type,
model.CheckFunc,
model.ErrorMessage
);
if ( ! string .IsNullOrEmpty(validateResult))
{
errMessage = validateResult;
return false ;
}
}
}
}
}
return true ;
}
}
public class User
{
[Validate(ValidateType.MinLength,MinLength = 5 )]
[Validate(ValidateType.IsPhone)]
public string Password { get ; set ; }
}
class Program
{
static void Main( string [] args)
{
string msg = string .Empty;
User user = new User();
user.Password = " 31234a " ;
if (Validate.GetValidateResult(user, out msg))
{
Console.WriteLine( " 测试通过 " );
}
else
{
Console.WriteLine(msg);
}
}
}
}
但是基于公司的项目是C#2.0的,所以改成了2.0:
testValidate.aspx


<!
DOCTYPE html PUBLIC
"
-//W3C//DTD XHTML 1.0 Transitional//EN
"
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
"
>
< html xmlns = " http://www.w3.org/1999/xhtml " >
< head runat = " server " >
< title ></ title >
</ head >
< body >
< form id = " form1 " runat = " server " >
< div >
Password: < asp:TextBox ID = " TextBox1 " runat = " server " ></ asp:TextBox >
< asp:Button ID = " Button1 "
runat = " server " Text = " Button " onclick = " Button1_Click " />
</ div >
</ form >
</ body >
</ html >
< html xmlns = " http://www.w3.org/1999/xhtml " >
< head runat = " server " >
< title ></ title >
</ head >
< body >
< form id = " form1 " runat = " server " >
< div >
Password: < asp:TextBox ID = " TextBox1 " runat = " server " ></ asp:TextBox >
< asp:Button ID = " Button1 "
runat = " server " Text = " Button " onclick = " Button1_Click " />
</ div >
</ form >
</ body >
</ html >
testValidate.aspx.cs


using
System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Reflection;
public partial class Darren_testValidate : System.Web.UI.Page
{
protected void Page_Load( object sender, EventArgs e)
{
}
protected void Button1_Click( object sender, EventArgs e)
{
string msg = string .Empty;
User user = new User();
user.Password = TextBox1.Text.Trim();
if (ValidateHelper.GetValidateResult(user, out msg))
{
Response.Write( " 测试通过 " );
// Console.WriteLine("测试通过");
}
else
{
Response.Write(msg);
// Console.WriteLine(msg);
}
}
}
[Flags]
public enum ValidateType
{
NotEmpty = 1 ,
MaxLength = 2 ,
MinLength = 4 ,
IsPhone = 8
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true )]
public class ValidateAttribute : Attribute
{
public ValidateAttribute(ValidateType validateType)
{
ValidateType = validateType;
}
private ValidateType validateType;
private int minLength;
private int maxLength;
public ValidateType ValidateType { get { return validateType;} set {validateType = value;} }
public int MinLength { get { return minLength;} set {minLength = value;} }
public int MaxLength { get { return maxLength; } set { maxLength = value; } }
}
public class ValidateModel
{
private ValidateType type;
private ValidateHelper.Func checkFunc;
private string errorMessage;
// private delegate bool func();
/// <summary>
/// 验证类型
/// </summary>
public ValidateType Type { get { return type; } set { type = value; } }
/// <summary>
/// 验证函数
/// </summary>
public ValidateHelper.Func CheckFunc { get { return checkFunc; } set { checkFunc = value; } }
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMessage { get { return errorMessage; } set { errorMessage = value; } }
}
public class ValidateHelper
{
public delegate bool Func();
/// <summary>
/// 检查需要验证的函数是否通过
/// </summary>
/// <param name="checkType"> 被检查类型 </param>
/// <param name="matchType"> 需要检查的类型 </param>
/// <param name="func"> 检查函数 </param>
/// <param name="errMessage"> 错误信息 </param>
/// <returns> Emtpy 验证通过,否则返回错误信息 </returns>
private static string CheckValidate(ValidateType checkType, ValidateType matchType, Func func, string errMessage)
{
if ((checkType & matchType) != 0 )
{
if (func())
{
return errMessage;
}
}
return String.Empty;
}
/// <summary>
/// 检查对象是否通过验证
/// </summary>
/// <param name="entityObject"> 需要检查的对象 </param>
/// <param name="errMessage"> 返回错误信息 </param>
/// <returns> true:通过,false:失败 </returns>
public static bool GetValidateResult( object entityObject, out string errMessage)
{
Type type = entityObject.GetType();
PropertyInfo[] properties = type.GetProperties();
string validateResult = string .Empty;
errMessage = string .Empty;
foreach (PropertyInfo property in properties)
{
object [] validateContent = property.GetCustomAttributes( typeof (ValidateAttribute), true );
if (validateContent != null )
{
object value = property.GetValue(entityObject, null );
foreach (ValidateAttribute validateAttribute in validateContent)
{
IList < ValidateModel > condition = new List < ValidateModel > ();
// 需要什么验证,在这里添加
ValidateModel vmode = new ValidateModel();
vmode.Type = ValidateType.NotEmpty;
vmode.CheckFunc = delegate { return (value == null || value.ToString().Length < 1 ); };
vmode.ErrorMessage = String.Format( " 元素{0}不能为空。 " , property.Name);
condition.Add(vmode);
vmode = new ValidateModel();
vmode.Type = ValidateType.MaxLength;
vmode.CheckFunc = delegate { return (value.ToString().Length > validateAttribute.MaxLength); };
vmode.ErrorMessage = String.Format( " 元素{0}长度不能超过{1} " , property.Name, validateAttribute.MaxLength);
condition.Add(vmode);
vmode = new ValidateModel();
vmode.Type = ValidateType.MinLength;
vmode.CheckFunc = delegate { return (value.ToString().Length < validateAttribute.MinLength); };
vmode.ErrorMessage = String.Format( " 元素{0}长度不能小于{1} " , property.Name, validateAttribute.MinLength);
condition.Add(vmode);
vmode = new ValidateModel();
vmode.Type = ValidateType.IsPhone;
vmode.CheckFunc = delegate { return ( ! System.Text.RegularExpressions.Regex.IsMatch(value.ToString(), @" ^\d+$ " )); };
vmode.ErrorMessage = String.Format( " 元素{0}必须是电话号码 " , property.Name);
condition.Add(vmode);
// condition.Add(new ValidateModel { Type = ValidateType.NotEmpty, CheckFunc = () => { return (value == null || value.ToString().Length < 1); }, ErrorMessage = String.Format("元素{0}不能为空。", property.Name) });
// condition.Add(new ValidateModel { Type = ValidateType.NotEmpty, CheckFunc = () => { return (value == null || value.ToString().Length < 1); }, ErrorMessage = String.Format("元素{0}不能为空。", property.Name) });
// condition.Add(new ValidateModel { Type = ValidateType.MaxLength, CheckFunc = () => { return (value.ToString().Length > validateAttribute.MaxLength); }, ErrorMessage = String.Format("元素{0}长度不能超过{1}", property.Name, validateAttribute.MaxLength) });
// condition.Add(new ValidateModel { Type = ValidateType.MinLength, CheckFunc = () => { return (value.ToString().Length < validateAttribute.MinLength); }, ErrorMessage = String.Format("元素{0}长度不能小于{1}", property.Name, validateAttribute.MinLength) });
// condition.Add(new ValidateModel { Type = ValidateType.IsPhone, CheckFunc = () => { return (!System.Text.RegularExpressions.Regex.IsMatch(value.ToString(), @"^\d+$")); }, ErrorMessage = String.Format("元素{0}必须是电话号码", property.Name) });
foreach (ValidateModel model in condition)
{
validateResult = CheckValidate(
validateAttribute.ValidateType,
model.Type,
model.CheckFunc,
model.ErrorMessage
);
if ( ! string .IsNullOrEmpty(validateResult))
{
errMessage = validateResult;
return false ;
}
}
}
}
}
return true ;
}
}
public class User
{
private string password;
[Validate(ValidateType.IsPhone | ValidateType.MinLength | ValidateType.NotEmpty, MinLength = 5 )]
public string Password { get { return password; } set { password = value; } }
}
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Reflection;
public partial class Darren_testValidate : System.Web.UI.Page
{
protected void Page_Load( object sender, EventArgs e)
{
}
protected void Button1_Click( object sender, EventArgs e)
{
string msg = string .Empty;
User user = new User();
user.Password = TextBox1.Text.Trim();
if (ValidateHelper.GetValidateResult(user, out msg))
{
Response.Write( " 测试通过 " );
// Console.WriteLine("测试通过");
}
else
{
Response.Write(msg);
// Console.WriteLine(msg);
}
}
}
[Flags]
public enum ValidateType
{
NotEmpty = 1 ,
MaxLength = 2 ,
MinLength = 4 ,
IsPhone = 8
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true )]
public class ValidateAttribute : Attribute
{
public ValidateAttribute(ValidateType validateType)
{
ValidateType = validateType;
}
private ValidateType validateType;
private int minLength;
private int maxLength;
public ValidateType ValidateType { get { return validateType;} set {validateType = value;} }
public int MinLength { get { return minLength;} set {minLength = value;} }
public int MaxLength { get { return maxLength; } set { maxLength = value; } }
}
public class ValidateModel
{
private ValidateType type;
private ValidateHelper.Func checkFunc;
private string errorMessage;
// private delegate bool func();
/// <summary>
/// 验证类型
/// </summary>
public ValidateType Type { get { return type; } set { type = value; } }
/// <summary>
/// 验证函数
/// </summary>
public ValidateHelper.Func CheckFunc { get { return checkFunc; } set { checkFunc = value; } }
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMessage { get { return errorMessage; } set { errorMessage = value; } }
}
public class ValidateHelper
{
public delegate bool Func();
/// <summary>
/// 检查需要验证的函数是否通过
/// </summary>
/// <param name="checkType"> 被检查类型 </param>
/// <param name="matchType"> 需要检查的类型 </param>
/// <param name="func"> 检查函数 </param>
/// <param name="errMessage"> 错误信息 </param>
/// <returns> Emtpy 验证通过,否则返回错误信息 </returns>
private static string CheckValidate(ValidateType checkType, ValidateType matchType, Func func, string errMessage)
{
if ((checkType & matchType) != 0 )
{
if (func())
{
return errMessage;
}
}
return String.Empty;
}
/// <summary>
/// 检查对象是否通过验证
/// </summary>
/// <param name="entityObject"> 需要检查的对象 </param>
/// <param name="errMessage"> 返回错误信息 </param>
/// <returns> true:通过,false:失败 </returns>
public static bool GetValidateResult( object entityObject, out string errMessage)
{
Type type = entityObject.GetType();
PropertyInfo[] properties = type.GetProperties();
string validateResult = string .Empty;
errMessage = string .Empty;
foreach (PropertyInfo property in properties)
{
object [] validateContent = property.GetCustomAttributes( typeof (ValidateAttribute), true );
if (validateContent != null )
{
object value = property.GetValue(entityObject, null );
foreach (ValidateAttribute validateAttribute in validateContent)
{
IList < ValidateModel > condition = new List < ValidateModel > ();
// 需要什么验证,在这里添加
ValidateModel vmode = new ValidateModel();
vmode.Type = ValidateType.NotEmpty;
vmode.CheckFunc = delegate { return (value == null || value.ToString().Length < 1 ); };
vmode.ErrorMessage = String.Format( " 元素{0}不能为空。 " , property.Name);
condition.Add(vmode);
vmode = new ValidateModel();
vmode.Type = ValidateType.MaxLength;
vmode.CheckFunc = delegate { return (value.ToString().Length > validateAttribute.MaxLength); };
vmode.ErrorMessage = String.Format( " 元素{0}长度不能超过{1} " , property.Name, validateAttribute.MaxLength);
condition.Add(vmode);
vmode = new ValidateModel();
vmode.Type = ValidateType.MinLength;
vmode.CheckFunc = delegate { return (value.ToString().Length < validateAttribute.MinLength); };
vmode.ErrorMessage = String.Format( " 元素{0}长度不能小于{1} " , property.Name, validateAttribute.MinLength);
condition.Add(vmode);
vmode = new ValidateModel();
vmode.Type = ValidateType.IsPhone;
vmode.CheckFunc = delegate { return ( ! System.Text.RegularExpressions.Regex.IsMatch(value.ToString(), @" ^\d+$ " )); };
vmode.ErrorMessage = String.Format( " 元素{0}必须是电话号码 " , property.Name);
condition.Add(vmode);
// condition.Add(new ValidateModel { Type = ValidateType.NotEmpty, CheckFunc = () => { return (value == null || value.ToString().Length < 1); }, ErrorMessage = String.Format("元素{0}不能为空。", property.Name) });
// condition.Add(new ValidateModel { Type = ValidateType.NotEmpty, CheckFunc = () => { return (value == null || value.ToString().Length < 1); }, ErrorMessage = String.Format("元素{0}不能为空。", property.Name) });
// condition.Add(new ValidateModel { Type = ValidateType.MaxLength, CheckFunc = () => { return (value.ToString().Length > validateAttribute.MaxLength); }, ErrorMessage = String.Format("元素{0}长度不能超过{1}", property.Name, validateAttribute.MaxLength) });
// condition.Add(new ValidateModel { Type = ValidateType.MinLength, CheckFunc = () => { return (value.ToString().Length < validateAttribute.MinLength); }, ErrorMessage = String.Format("元素{0}长度不能小于{1}", property.Name, validateAttribute.MinLength) });
// condition.Add(new ValidateModel { Type = ValidateType.IsPhone, CheckFunc = () => { return (!System.Text.RegularExpressions.Regex.IsMatch(value.ToString(), @"^\d+$")); }, ErrorMessage = String.Format("元素{0}必须是电话号码", property.Name) });
foreach (ValidateModel model in condition)
{
validateResult = CheckValidate(
validateAttribute.ValidateType,
model.Type,
model.CheckFunc,
model.ErrorMessage
);
if ( ! string .IsNullOrEmpty(validateResult))
{
errMessage = validateResult;
return false ;
}
}
}
}
}
return true ;
}
}
public class User
{
private string password;
[Validate(ValidateType.IsPhone | ValidateType.MinLength | ValidateType.NotEmpty, MinLength = 5 )]
public string Password { get { return password; } set { password = value; } }
}
有博友提到“System.ComponentModel.DataAnnotations命名空间中有很多用来验证的Attribute。”也能进行验证,但是自己是作为练习,多写一些代码也无妨。