.Net Framework CF版中没有Cookie容器,也能使用Session保存会话状态
最近在做一个项目,这个项目是采用的Web服务,客户端是WinCE 4.1+.Net Framework CF版。大家知道,要保存当前会话状态(当前登录的用户信息,当前操作的单据等)最好是用Session来保存,Web service中也提供了session的支持。在一般的应用中使用Session是没有问题的,只需要把声明一个CookieContainer对象就可以了。如下:
Service s=new Service();
s.CookieContainer=new CookieContainer();
s.CookieContainer=new CookieContainer();
经过几天的思考后,终于想到了一个解决办法:在服务器端用一个静态的HashTable模拟Session对象,用客户端的IP地址作为关键字,代码如下:
1public class Global : System.Web.HttpApplication
2{
3 private System.ComponentModel.IContainer components = null;
4 private static Hashtable UserSession;
5 private static int Session_timeout; //Session超时时间
6
7
8 public Global()
9 {
10 InitializeComponent();
11 }
12
13 protected void Application_Start(Object sender, EventArgs e)
14 {
15 UserSession=new Hashtable();
16 Session_timeout=60;
17 }
18
19 protected void Session_Start(Object sender, EventArgs e)
20 {
21 Session["ip"]=Request.UserHostAddress;
22
23 //检测到该Ip是第一次访问或者Session已经超时,则把当前Session加入到HashTable中
24 if(UserSession[Request.UserHostAddress]==null || DateTime.Compare(DateTime.Now,((DateTime)UserSession[Request.UserHostAddress+"_time"]).AddMinutes(Session.Timeout))>0)
25 {
26 UserSession[Request.UserHostAddress]=Session;
27 }
28 //保存最近一次访问时间
29 UserSession[Request.UserHostAddress+"_time"]=DateTime.Now;
30 }
31
32 //外部的函数可以通过这个函数读取Session
33 public static System.Web.SessionState.HttpSessionState mySession(string IP)
34 {
35 return (System.Web.SessionState.HttpSessionState)UserSession[IP];
36 }
37
38 //检测当前HashTable保存的Session有没有已经超时的,有则清除掉
39 private static bool checkSession(string HostAddress)
40 {
41 try
42 {
43 if(DateTime.Compare(DateTime.Now,((DateTime)UserSession[HostAddress+"_time"]).AddMinutes(Session_timeout).AddSeconds(-1))>0)
44 {
45 UserSession.Remove(HostAddress);
46 UserSession.Remove(HostAddress+"_time");
47 return true;
48 }
49 else
50 {
51 return false;
52 }
53 }
54 catch
55 {
56 if(UserSession.ContainsKey(HostAddress))
57 UserSession.Remove(HostAddress);
58 return false;
59 }
60 }
61
62 protected void Session_End(Object sender, EventArgs e)
63 {
64 checkSession(Request.UserHostAddress);
65 }
66}
2{
3 private System.ComponentModel.IContainer components = null;
4 private static Hashtable UserSession;
5 private static int Session_timeout; //Session超时时间
6
7
8 public Global()
9 {
10 InitializeComponent();
11 }
12
13 protected void Application_Start(Object sender, EventArgs e)
14 {
15 UserSession=new Hashtable();
16 Session_timeout=60;
17 }
18
19 protected void Session_Start(Object sender, EventArgs e)
20 {
21 Session["ip"]=Request.UserHostAddress;
22
23 //检测到该Ip是第一次访问或者Session已经超时,则把当前Session加入到HashTable中
24 if(UserSession[Request.UserHostAddress]==null || DateTime.Compare(DateTime.Now,((DateTime)UserSession[Request.UserHostAddress+"_time"]).AddMinutes(Session.Timeout))>0)
25 {
26 UserSession[Request.UserHostAddress]=Session;
27 }
28 //保存最近一次访问时间
29 UserSession[Request.UserHostAddress+"_time"]=DateTime.Now;
30 }
31
32 //外部的函数可以通过这个函数读取Session
33 public static System.Web.SessionState.HttpSessionState mySession(string IP)
34 {
35 return (System.Web.SessionState.HttpSessionState)UserSession[IP];
36 }
37
38 //检测当前HashTable保存的Session有没有已经超时的,有则清除掉
39 private static bool checkSession(string HostAddress)
40 {
41 try
42 {
43 if(DateTime.Compare(DateTime.Now,((DateTime)UserSession[HostAddress+"_time"]).AddMinutes(Session_timeout).AddSeconds(-1))>0)
44 {
45 UserSession.Remove(HostAddress);
46 UserSession.Remove(HostAddress+"_time");
47 return true;
48 }
49 else
50 {
51 return false;
52 }
53 }
54 catch
55 {
56 if(UserSession.ContainsKey(HostAddress))
57 UserSession.Remove(HostAddress);
58 return false;
59 }
60 }
61
62 protected void Session_End(Object sender, EventArgs e)
63 {
64 checkSession(Request.UserHostAddress);
65 }
66}
下面是调用代码:
1public class Service : System.Web.Services.WebService
2{
3 public Service()
4 {
5 InitializeComponent();
6
7 }
8 #region 组件设计器生成的代码
9
10 //Web 服务设计器所必需的
11 private IContainer components = null;
12
13 /// <summary>
14 /// 设计器支持所需的方法 - 不要使用代码编辑器修改
15 /// 此方法的内容。
16 /// </summary>
17 private void InitializeComponent()
18 {
19
20 }
21
22 /// <summary>
23 /// 清理所有正在使用的资源。
24 /// </summary>
25 protected override void Dispose( bool disposing )
26 {
27 if(disposing && components != null)
28 {
29 components.Dispose();
30 }
31 base.Dispose(disposing);
32 }
33
34 #endregion
35
36 private object ReadCurrentSession(string Key)
37 {
38 return Global.mySession(Session["ip"].ToString())[Key];
39 }
40 private void SetCurrentSession(string Key,object Value)
41 {
42 Global.mySession(Session["ip"].ToString())[Key]=Value;
43 }
44
45 //测试方法1:使用Hashtable中保存的Session
46 [WebMethod(EnableSession=true)]
47 public int Add()
48 {
49 int count;
50 if(ReadCurrentSession("count")==null)
51 count=0;
52 else
53 count=Convert.ToInt32(ReadCurrentSession("count"));
54 count++;
55 SetCurrentSession("count",count);
56 return count;
57 }
58
59 //测试方法2:使用系统内建的Session
60 [WebMethod(EnableSession=true)]
61 public int Add2()
62 {
63 int count;
64 if(Session["count2"]==null)
65 count=0;
66 else
67 count=Convert.ToInt32(Session["count2"]);
68 count++;
69 Session["count2"]=count;
70 return count;
71 }
72}
2{
3 public Service()
4 {
5 InitializeComponent();
6
7 }
8 #region 组件设计器生成的代码
9
10 //Web 服务设计器所必需的
11 private IContainer components = null;
12
13 /// <summary>
14 /// 设计器支持所需的方法 - 不要使用代码编辑器修改
15 /// 此方法的内容。
16 /// </summary>
17 private void InitializeComponent()
18 {
19
20 }
21
22 /// <summary>
23 /// 清理所有正在使用的资源。
24 /// </summary>
25 protected override void Dispose( bool disposing )
26 {
27 if(disposing && components != null)
28 {
29 components.Dispose();
30 }
31 base.Dispose(disposing);
32 }
33
34 #endregion
35
36 private object ReadCurrentSession(string Key)
37 {
38 return Global.mySession(Session["ip"].ToString())[Key];
39 }
40 private void SetCurrentSession(string Key,object Value)
41 {
42 Global.mySession(Session["ip"].ToString())[Key]=Value;
43 }
44
45 //测试方法1:使用Hashtable中保存的Session
46 [WebMethod(EnableSession=true)]
47 public int Add()
48 {
49 int count;
50 if(ReadCurrentSession("count")==null)
51 count=0;
52 else
53 count=Convert.ToInt32(ReadCurrentSession("count"));
54 count++;
55 SetCurrentSession("count",count);
56 return count;
57 }
58
59 //测试方法2:使用系统内建的Session
60 [WebMethod(EnableSession=true)]
61 public int Add2()
62 {
63 int count;
64 if(Session["count2"]==null)
65 count=0;
66 else
67 count=Convert.ToInt32(Session["count2"]);
68 count++;
69 Session["count2"]=count;
70 return count;
71 }
72}
经过测试,以上代码完全可行,只是使用的时候要小心,因为同一个IP地址访问Web服务,即使是退出客户端应用程序,换个操作员重新登录,仍然会使用同一个Session,这就需要在服务器端判断,在适当的时候启用新的Session会话.