做项目的过程中,经常会遇到页面传参的问题。对于简单的参数传递,我相信大家都会处理,直接在新页面的URL后添加诸如name=sangplus&age=18形式的参数变量就行了。然而一般我们遇到的问题可能要比这个棘手一些,我们解决这些问题的方法也可能有很多种,但对于初学者来说,往往无所选择。下面我介绍一种自己摸索的方法,虽然在某些方面还有一些局限性,不过我相信已经可以很好的解决你的问题了。
- 方法原理及代码
首先,从System.Web.UI.Page继承一个类BasePage作为其它页面的基类,BasePage定义两个hashTable类型的属性TargetParams和SourceParams,分别用Session和ViewState来存储,它们代表调用页面中要传递的参数集合和接收页面中要接收的参数集合。然后BasePage覆写System.Web.UI.Page的OnLoad方法,当第一次进入页面的时候,把Session的内容赋给ViewState,并清空Session中的相应内容。
然后,在需要传参的页面直接调用基类的属性即可。
BasePage的代码如下:
Code
1 public class BasePage:System.Web.UI.Page
2 {
3 protected Hashtable TargetParams
4 {
5 get
6 {
7 if (Session["_PageParams_"] == null)
8 Session["_PageParams_"] = new Hashtable();
9 return (Hashtable)Session["_PageParams_"];
10 }
11 }
12 protected Hashtable SourceParams
13 {
14 get
15 {
16 if (ViewState["_PageParams_"] == null)
17 ViewState["_PageParams_"] = new Hashtable();
18 return (Hashtable)ViewState["_PageParams_"];
19 }
20 }
21 protected override void OnLoad(EventArgs e)
22 {
23 if (!IsPostBack)
24 {
25 if (Session["_PageParams_"] != null)
26 {
27 ViewState["_PageParams_"] = Session["_PageParams_"] as Hashtable;
28 Session["_PageParams_"] = null;
29 }
30 else
31 {
32 ViewState["_PageParams_"] = new Hashtable();
33 }
34 }
35 base.OnLoad(e);
36 }
37 }
1 public class BasePage:System.Web.UI.Page
2 {
3 protected Hashtable TargetParams
4 {
5 get
6 {
7 if (Session["_PageParams_"] == null)
8 Session["_PageParams_"] = new Hashtable();
9 return (Hashtable)Session["_PageParams_"];
10 }
11 }
12 protected Hashtable SourceParams
13 {
14 get
15 {
16 if (ViewState["_PageParams_"] == null)
17 ViewState["_PageParams_"] = new Hashtable();
18 return (Hashtable)ViewState["_PageParams_"];
19 }
20 }
21 protected override void OnLoad(EventArgs e)
22 {
23 if (!IsPostBack)
24 {
25 if (Session["_PageParams_"] != null)
26 {
27 ViewState["_PageParams_"] = Session["_PageParams_"] as Hashtable;
28 Session["_PageParams_"] = null;
29 }
30 else
31 {
32 ViewState["_PageParams_"] = new Hashtable();
33 }
34 }
35 base.OnLoad(e);
36 }
37 }
发送参数页面PageA的后台代码
Code
1 public partial class PageA : BasePage
2 {
3 protected void Page_Load(object sender, EventArgs e)
4 {
5 }
6
7 protected void btRedirect_Click(object sender, EventArgs e)
8 {
9 TargetParams["para1"] = tb1.Text;
10 TargetParams["para2"] = tb2.Text;
11 Response.Redirect("PageB.aspx");
12 }
13
14 protected void Button1_Click(object sender, EventArgs e)
15 {
16 myClass mc = new myClass();
17 mc.name = "sangplus";
18 mc.age = 18;
19 mc.address = "北京市中关村牛B大厦1818号";
20
21 TargetParams["myClass"] = mc;
22 Response.Redirect("PageB.aspx");
23 }
24 }
1 public partial class PageA : BasePage
2 {
3 protected void Page_Load(object sender, EventArgs e)
4 {
5 }
6
7 protected void btRedirect_Click(object sender, EventArgs e)
8 {
9 TargetParams["para1"] = tb1.Text;
10 TargetParams["para2"] = tb2.Text;
11 Response.Redirect("PageB.aspx");
12 }
13
14 protected void Button1_Click(object sender, EventArgs e)
15 {
16 myClass mc = new myClass();
17 mc.name = "sangplus";
18 mc.age = 18;
19 mc.address = "北京市中关村牛B大厦1818号";
20
21 TargetParams["myClass"] = mc;
22 Response.Redirect("PageB.aspx");
23 }
24 }
(其中myClass自定义类型,是被传递的参数类型)
Code
1
2 [Serializable]
3 public class myClass
4 {
5 public string name;
6 public int age;
7 public string address;
8 }
1
2 [Serializable]
3 public class myClass
4 {
5 public string name;
6 public int age;
7 public string address;
8 }
接收参数页面PageB的后台代码
Code
1 public partial class PageB : BasePage
2 {
3 protected void Page_Load(object sender, EventArgs e)
4 {
5
6 if (SourceParams.ContainsKey("para1"))
7 {
8 tb1.Text = SourceParams["para1"] as string;
9 }
10 if (SourceParams.ContainsKey("para1"))
11 {
12 tb2.Text = SourceParams["para2"] as string;
13 }
14
15 if (SourceParams.ContainsKey("myClass"))
16 {
17 myClass mc = SourceParams["myClass"] as myClass;
18 tb1.Text = mc.name;
19 tb2.Text = mc.age.ToString();
20 }
21
22 }
23 }
1 public partial class PageB : BasePage
2 {
3 protected void Page_Load(object sender, EventArgs e)
4 {
5
6 if (SourceParams.ContainsKey("para1"))
7 {
8 tb1.Text = SourceParams["para1"] as string;
9 }
10 if (SourceParams.ContainsKey("para1"))
11 {
12 tb2.Text = SourceParams["para2"] as string;
13 }
14
15 if (SourceParams.ContainsKey("myClass"))
16 {
17 myClass mc = SourceParams["myClass"] as myClass;
18 tb1.Text = mc.name;
19 tb2.Text = mc.age.ToString();
20 }
21
22 }
23 }
页面,参数,基类之间的关系图如下
- 方法特点
-
实用性好:我想大家在用Url进行参数传递的时候,遇到的问题主要是两类:一是中文等参数的编解码问题,二是复杂类型参数(如自定义类型)的传递问题。而通过我们的方法可以很好的解决这个问题,因而该方法应该能解决大家在进行参数传递时遇到的大部分问题,相信大家理解了以后会经常应用该方法的。
-
使用方法简单:在Redirect之前, 把参数放入TargetParams中。在接收页面中直接从SourceParams中取出参数。不需要进行过多的编码,解码等操作。
-
安全性也不错:因为不用在客户端的Url里面放参数字符串,因而客户端不能直接看到参数内容,参数内容的安全性由M$内建的ViewState来支持,大家应该可以放心。
-
性能也不错:虽然该方法使用了Session,但是由于Session仅在Redirect跳转之前才使用,而在第一进入新页面的时候,Session的内容已经被清空。因而客户在浏览网页内容的时候,服务器上的Session其实是没有存放参数内容的,从而不会给服务器带来任何压力。
-
注意事项
-
由于要把参数放入ViewState,因而要求被传递的参数可序列化。关于这一点,c#的基础数据类型都没有问题,简单的自定义类型,大家可参考上面例子中的myClass类,只要在类定义前放一句[Serializable]即可,复杂的自定类型,只要实现了ISerializable接口也是没有任何问题的。
-
由于参数传递以后,新页面会把参数放入ViewState中,而ViewState在服务器和客户端之间的传输也是要占用一部分网络资源的,因而请大家尽量不要传递数据量很大的参数,如DataSet等。
该方法仅是工作中自己的一个心得,Baidu了半天也没见别人说出个好的方法,所以发出来以供大家参考。限于本人水平,文中可能有很多地方说的不对,欢迎各位高手批评指正。