当我在页面中使用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.cnblogs.com/zhuqil/archive/2010/01/30/ViewStateAttribute.html