2 // System.Web.SessionState.SessionSQLServerHandler
5 // Jackson Harper (jackson@ximian.com)
7 // (C) 2003 Novell, Inc. (http://www.novell.com), All rights reserved
13 using System.Reflection;
14 using System.Configuration;
15 using System.Collections.Specialized;
17 namespace System.Web.SessionState {
19 internal class SessionSQLServerHandler : ISessionHandler
21 const string CookieName = "ASPSESSION";
22 const int DefTimeout = 600;
24 private Type cncType = null;
25 private IDbConnection cnc = null;
26 private SessionConfig config;
28 public void Dispose ()
36 public void Init (HttpApplication context, SessionConfig config)
38 string connectionTypeName;
39 string providerAssemblyName;
44 GetConnectionData (out providerAssemblyName, out connectionTypeName, out cncString);
45 if (cncType == null) {
46 Assembly dbAssembly = Assembly.Load (providerAssemblyName);
47 cncType = dbAssembly.GetType (connectionTypeName, true);
48 if (!typeof (IDbConnection).IsAssignableFrom (cncType))
49 throw new ApplicationException ("The type '" + cncType +
50 "' does not implement IDB Connection.\n" +
51 "Check 'DbConnectionType' in server.exe.config.");
54 cnc = (IDbConnection) Activator.CreateInstance (cncType);
55 cnc.ConnectionString = cncString;
58 } catch (Exception exc) {
64 public void UpdateHandler (HttpContext context)
66 if (context.Session == null)
69 string id = context.Session.SessionID;
70 SessionDictionary dict = context.Session.SessionDictionary;
72 UpdateSession (id, dict);
75 public bool UpdateContext (HttpContext context)
77 HttpSessionState session = null;
78 string id = GetId (context);
81 session = SelectSession (id);
82 if (session != null) {
83 context.SetSession (session);
88 id = System.Guid.NewGuid ().ToString ();
89 session = new HttpSessionState (id, new SessionDictionary (),
90 new HttpStaticObjectsCollection (), config.Timeout, true,
91 false, SessionStateMode.SQLServer, false);
93 InsertSession (session, config.Timeout);
94 context.SetSession (session);
95 context.Session.IsNewSession = true;
96 context.Response.AppendCookie (new HttpCookie (CookieName, id));
101 private void GetConnectionData (out string providerAssembly,
102 out string cncTypeName, out string cncString)
104 providerAssembly = null;
108 NameValueCollection config = ConfigurationSettings.AppSettings as NameValueCollection;
109 if (config != null) {
110 foreach (string s in config.Keys) {
111 if (0 == String.Compare ("StateDBProviderAssembly", s, true)) {
112 providerAssembly = config [s];
113 } else if (0 == String.Compare ("StateDBConnectionType", s, true)) {
114 cncTypeName = config [s];
119 cncString = this.config.SqlConnectionString;
121 if (providerAssembly == null || providerAssembly == String.Empty)
122 providerAssembly = "Npgsql.dll";
124 if (cncTypeName == null || cncTypeName == String.Empty)
125 cncTypeName = "Npgsql.NpgsqlConnection";
127 if (cncString == null || cncString == String.Empty)
128 cncString = "SERVER=127.0.0.1;USER ID=monostate;PASSWORD=monostate;dbname=monostate";
131 private HttpSessionState SelectSession (string id)
133 HttpSessionState session = null;
134 IDbCommand command = cnc.CreateCommand();
137 string select = "SELECT * from aspstatetempsessions WHERE SessionID = :SessionID";
139 command.CommandText = select;
141 command.Parameters.Add (CreateParam (command, DbType.String, ":SessionID", id));
144 reader = command.ExecuteReader ();
149 SessionDictionary dict = null;
150 MemoryStream stream = null;
151 int len = (int) reader.GetBytes (reader.FieldCount-1, 0, null, 0, 0);
152 byte[] data = new byte[len];
153 reader.GetBytes (reader.FieldCount-1, 0, data, 0, len);
155 stream = new MemoryStream (data);
156 dict = SessionDictionary.Deserialize (new BinaryReader (stream));
164 session = new HttpSessionState (id, dict,
165 new HttpStaticObjectsCollection (),
167 SessionStateMode.SQLServer, false);
175 private void InsertSession (HttpSessionState session, int timeout)
177 IDbCommand command = cnc.CreateCommand ();
178 IDataParameterCollection param;
180 string insert = "INSERT INTO ASPStateTempSessions VALUES " +
181 "(:SessionID, :Created, :Expires, :Timeout, :SessionData)";
183 command.CommandText = insert;
185 param = command.Parameters;
186 param.Add (CreateParam (command, DbType.String, ":SessionID", session.SessionID));
187 param.Add (CreateParam (command, DbType.DateTime, ":Created", DateTime.Now));
188 param.Add (CreateParam (command, DbType.DateTime, ":Expires", Tommorow ()));
189 param.Add (CreateParam (command, DbType.Int32, ":Timeout", timeout));
190 param.Add (CreateParam (command, DbType.Binary, ":SessionData",
191 GetDictData (session.SessionDictionary)));
193 command.ExecuteNonQuery ();
196 private void UpdateSession (string id, SessionDictionary dict)
198 IDbCommand command = cnc.CreateCommand ();
199 IDataParameterCollection param;
201 string update = "UPDATE ASPStateTempSessions SET " +
202 "SessionData = :SessionData WHERE SessionId = :SessionID";
204 command.CommandText = update;
206 param = command.Parameters;
207 param.Add (CreateParam (command, DbType.String, ":SessionID", id));
208 param.Add (CreateParam (command, DbType.Binary, ":SessionData",
209 GetDictData (dict)));
211 command.ExecuteNonQuery ();
214 private IDataParameter CreateParam (IDbCommand command, DbType type,
215 string name, object value)
217 IDataParameter result = command.CreateParameter ();
218 result.DbType = type;
219 result.ParameterName = name;
220 result.Value = value;
224 private byte[] GetDictData (SessionDictionary dict)
226 MemoryStream stream = null;
228 stream = new MemoryStream ();
229 dict.Serialize (new BinaryWriter (stream));
230 return stream.GetBuffer ();
239 private DateTime Tommorow ()
241 return DateTime.Now.AddDays (1);
244 private string GetId (HttpContext context)
246 if (!config.CookieLess &&
247 context.Request.Cookies [CookieName] != null)
248 return context.Request.Cookies [CookieName].Value;