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 int DefTimeout = 600;
23 private Type cncType = null;
24 private IDbConnection cnc = null;
25 private SessionConfig config;
27 public void Dispose ()
35 public void Init (HttpApplication context, SessionConfig config)
37 string connectionTypeName;
38 string providerAssemblyName;
43 GetConnectionData (out providerAssemblyName, out connectionTypeName, out cncString);
44 if (cncType == null) {
45 Assembly dbAssembly = Assembly.Load (providerAssemblyName);
46 cncType = dbAssembly.GetType (connectionTypeName, true);
47 if (!typeof (IDbConnection).IsAssignableFrom (cncType))
48 throw new ApplicationException ("The type '" + cncType +
49 "' does not implement IDB Connection.\n" +
50 "Check 'DbConnectionType' in server.exe.config.");
53 cnc = (IDbConnection) Activator.CreateInstance (cncType);
54 cnc.ConnectionString = cncString;
57 } catch (Exception exc) {
63 public void UpdateHandler (HttpContext context, SessionStateModule module)
65 if (context.Session == null)
68 string id = context.Session.SessionID;
69 SessionDictionary dict = context.Session.SessionDictionary;
71 UpdateSession (id, dict);
74 public bool UpdateContext (HttpContext context, SessionStateModule module)
76 HttpSessionState session = null;
77 string id = SessionId.Lookup (context.Request, config.CookieLess);
80 session = SelectSession (id);
81 if (session != null) {
82 context.SetSession (session);
87 id = SessionId.Create (module.Rng);
88 session = new HttpSessionState (id, new SessionDictionary (),
89 new HttpStaticObjectsCollection (), config.Timeout, true,
90 false, SessionStateMode.SQLServer, false);
92 InsertSession (session, config.Timeout);
93 context.SetSession (session);
94 context.Session.IsNewSession = true;
99 private void GetConnectionData (out string providerAssembly,
100 out string cncTypeName, out string cncString)
102 providerAssembly = null;
106 NameValueCollection config = ConfigurationSettings.AppSettings as NameValueCollection;
107 if (config != null) {
108 foreach (string s in config.Keys) {
109 if (0 == String.Compare ("StateDBProviderAssembly", s, true)) {
110 providerAssembly = config [s];
111 } else if (0 == String.Compare ("StateDBConnectionType", s, true)) {
112 cncTypeName = config [s];
117 cncString = this.config.SqlConnectionString;
119 if (providerAssembly == null || providerAssembly == String.Empty)
120 providerAssembly = "Npgsql.dll";
122 if (cncTypeName == null || cncTypeName == String.Empty)
123 cncTypeName = "Npgsql.NpgsqlConnection";
125 if (cncString == null || cncString == String.Empty)
126 cncString = "SERVER=127.0.0.1;USER ID=monostate;PASSWORD=monostate;dbname=monostate";
129 private HttpSessionState SelectSession (string id)
131 HttpSessionState session = null;
132 IDbCommand command = cnc.CreateCommand();
135 string select = "SELECT * from aspstatetempsessions WHERE SessionID = :SessionID";
137 command.CommandText = select;
139 command.Parameters.Add (CreateParam (command, DbType.String, ":SessionID", id));
142 reader = command.ExecuteReader ();
147 SessionDictionary dict;
148 HttpStaticObjectsCollection sobjs;
150 dict = SessionDictionary.FromByteArray (ReadBytes (reader, reader.FieldCount-1));
151 sobjs = HttpStaticObjectsCollection.FromByteArray (ReadBytes (reader, reader.FieldCount-2));
153 session = new HttpSessionState (id, dict, sobjs, 100, true, false,
154 SessionStateMode.SQLServer, false);
161 private void InsertSession (HttpSessionState session, int timeout)
163 IDbCommand command = cnc.CreateCommand ();
164 IDataParameterCollection param;
166 string insert = "INSERT INTO ASPStateTempSessions VALUES " +
167 "(:SessionID, :Created, :Expires, :Timeout, :StaticObjectsData, :SessionData)";
169 command.CommandText = insert;
171 param = command.Parameters;
172 param.Add (CreateParam (command, DbType.String, ":SessionID", session.SessionID));
173 param.Add (CreateParam (command, DbType.DateTime, ":Created", DateTime.Now));
174 param.Add (CreateParam (command, DbType.DateTime, ":Expires", Tommorow ()));
175 param.Add (CreateParam (command, DbType.Int32, ":Timeout", timeout));
176 param.Add (CreateParam (command, DbType.Binary, ":StaticObjectsData",
177 session.StaticObjects.ToByteArray ()));
178 param.Add (CreateParam (command, DbType.Binary, ":SessionData",
179 session.SessionDictionary.ToByteArray ()));
181 command.ExecuteNonQuery ();
184 private void UpdateSession (string id, SessionDictionary dict)
186 IDbCommand command = cnc.CreateCommand ();
187 IDataParameterCollection param;
189 string update = "UPDATE ASPStateTempSessions SET " +
190 "SessionData = :SessionData WHERE SessionId = :SessionID";
192 command.CommandText = update;
194 param = command.Parameters;
195 param.Add (CreateParam (command, DbType.String, ":SessionID", id));
196 param.Add (CreateParam (command, DbType.Binary, ":SessionData",
197 dict.ToByteArray ()));
199 command.ExecuteNonQuery ();
202 private IDataParameter CreateParam (IDbCommand command, DbType type,
203 string name, object value)
205 IDataParameter result = command.CreateParameter ();
206 result.DbType = type;
207 result.ParameterName = name;
208 result.Value = value;
212 private DateTime Tommorow ()
214 return DateTime.Now.AddDays (1);
217 private byte [] ReadBytes (IDataReader reader, int index)
219 int len = (int) reader.GetBytes (reader.FieldCount-1, 0, null, 0, 0);
220 byte [] data = new byte [len];
221 reader.GetBytes (index, 0, data, 0, len);