Demo:/Files/zhuqil/WebApplication4.rar
当我在页面中使用ViewState ,通常是用一个属性表示,例如:
private int ViewState_UserID { get { return (int) ViewState["UserId"]; } set { ViewState["UserId"] = value; } }写这样一组代码感觉比较麻烦,如果能像下面这样简单地使用就好了。
[ViewStateProperty("UserID")] protected int ViewState_UserID { get; set;}或者
[ViewStateProperty] protected int ViewState_UserID { get; set;}这里介绍一种超级简单的方式去实现:使用Attribute。
第一步:创建BasePage 类,它继承System.Web.UI.Page。这里使用了Reflection和LINQ。
using System.Reflection; using System.Linq; public class BasePage : System.Web.UI.Page第二步:在BasePage中使用一个内部类ViewStateProperty ,这个类继承Attribute 。用Attribute的目的是描述页面中哪个属性是viewstate属性。用这个属性来标识viewstate属性,因此它应该BasePage内部。
代码 -->[AttributeUsage(AttributeTargets.Property)] public class ViewStateProperty : Attribute { public string ViewStateName { get; private set; } internal ViewStateProperty(){ this.ViewStateName = string.Empty; } public ViewStateProperty(string in_ViewStateName){ this.ViewStateName = in_ViewStateName; } }
[AttributeUsage(AttributeTargets.Property)]意味着这个attribute 只对property类型可用。在public ViewStateProperty(string in_ViewStateName)中初始化ViewState 的名称。默认情况下,ViewState 的名字为空。如果你想在设置attribute的时候初始化ViewState的名字时,要将默认构造函数设置为私有的。
第三步:在BasePage中,创建一个ViewStateProperties变量来存储有ViewStateProperty标签的属性,在BasePage默认构造函数中初始化它们:
private PropertyInfo[] ViewStateProperties; protected BasePage() { this.ViewStateProperties = GetType().GetProperties( BindingFlags.NonPublic | BindingFlags.Instance).Where( p => p.GetCustomAttributes(typeof(ViewStateProperty), true).Length > 0).ToArray(); }
GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance)通过反射获得所有的public 和protected属性 。Where(p=>p.GetCustomAttributes(typeof(ViewStateProperty), true).Length > 0)用来过滤有ViewStateProperty修饰的属性。
第四步: 在BasePage中重载LoadViewState 和SaveViewState方法
protected override void LoadViewState(object savedState) { base.LoadViewState(savedState); foreach (PropertyInfo property in ViewStateProperties) { ViewStateProperty[] attributes = (ViewStateProperty[]) property.GetCustomAttributes(typeof(ViewStateProperty), false); var LocalName = (string.Empty == attributes[0].ViewStateName) ? property.Name : attributes[0].ViewStateName; if (ViewState[LocalName] != null) property.SetValue(this, ViewState[LocalName], null); } } protected override object SaveViewState() { foreach (PropertyInfo property in ViewStateProperties) { ViewStateProperty[] attributes = (ViewStateProperty[]) property.GetCustomAttributes(typeof(ViewStateProperty), false); var LocalName = (string.Empty == attributes[0].ViewStateName)? property.Name:attributes[0].ViewStateName; ViewState[LocalName] = property.GetValue(this, null); } return base.SaveViewState(); }
目的是根据name设置viewstate值,这个name设置在ViewStateProperty标签上,加载ViewState的值,并赋值给有ViewStateProperty修饰的属性
使用它:
[ViewStateProperty("UserID")] protected int ViewState_UserID { get; set;}
或者:
[ViewStateProperty] protected int ViewState_UserID { get; set;}
在第一个,设置一个名为UserID的ViewState,第二个,您设置名为ViewState_UserID的ViewState。
注意:要实现这样的属性,您不能将它们设置为私有的,因为 GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance) 不能返回private 属性,设置为protected足以满足我们的需要。
参考原文:http://www.codeproject.com/KB/viewstate/ViewStateAttribute.aspx