| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 |
- //
- // System.Web.UI.WebControls.SqlProfileProvider.cs
- //
- // Authors:
- // Chris Toshok ([email protected])
- // Vladimir Krasnov ([email protected])
- //
- // (C) 2006 Novell, Inc (http://www.novell.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- #if NET_2_0
- using System;
- using System.Data;
- using System.Data.Common;
- using System.Collections;
- using System.Globalization;
- using System.Configuration;
- using System.Configuration.Provider;
- using System.Web.Configuration;
- using System.Collections.Specialized;
- using System.IO;
- using System.Text;
- namespace System.Web.Profile
- {
- public class SqlProfileProvider : ProfileProvider
- {
- ConnectionStringSettings connectionString;
- DbProviderFactory factory;
- string applicationName;
- public override int DeleteInactiveProfiles (ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
- {
- using (DbConnection connection = CreateConnection ()) {
- DbCommand command = factory.CreateCommand ();
- command.Connection = connection;
- command.CommandType = CommandType.StoredProcedure;
- command.CommandText = @"aspnet_Profile_DeleteInactiveProfiles";
- AddParameter (command, "ApplicationName", ApplicationName);
- AddParameter (command, "ProfileAuthOptions", authenticationOption);
- AddParameter (command, "InactiveSinceDate", userInactiveSinceDate);
- DbParameter returnValue = AddParameter (command, null, ParameterDirection.ReturnValue, null);
- command.ExecuteNonQuery ();
- int retVal = GetReturnValue (returnValue);
- return retVal;
- }
- }
- public override int DeleteProfiles (ProfileInfoCollection profiles)
- {
- if (profiles == null)
- throw new ArgumentNullException ("prfoles");
- if (profiles.Count == 0)
- throw new ArgumentException ("prfoles");
- string [] usernames = new string [profiles.Count];
- int i = 0;
- foreach (ProfileInfo pi in profiles) {
- if (pi.UserName == null)
- throw new ArgumentNullException ("element in profiles collection is null");
- if (pi.UserName.Length == 0 || pi.UserName.Length > 256 || pi.UserName.IndexOf (",") != -1)
- throw new ArgumentException ("element in profiles collection in illegal format");
- usernames [i++] = pi.UserName;
- }
- return DeleteProfilesInternal (usernames);
- }
- public override int DeleteProfiles (string [] usernames)
- {
- if (usernames == null)
- throw new ArgumentNullException ("usernames");
- Hashtable users = new Hashtable ();
- foreach (string username in usernames) {
- if (username == null)
- throw new ArgumentNullException ("element in usernames array is null");
- if (username.Length == 0 || username.Length > 256 || username.IndexOf (",") != -1)
- throw new ArgumentException ("element in usernames array in illegal format");
- if (users.ContainsKey(username))
- throw new ArgumentException ("duplicate element in usernames array");
- users.Add (username, username);
- }
- return DeleteProfilesInternal (usernames);
- }
- private int DeleteProfilesInternal (string [] usernames)
- {
- using (DbConnection connection = CreateConnection ()) {
- DbCommand command = factory.CreateCommand ();
- command.Connection = connection;
- command.CommandType = CommandType.StoredProcedure;
- command.CommandText = @"aspnet_Profile_DeleteProfiles";
- AddParameter (command, "ApplicationName", ApplicationName);
- AddParameter (command, "UserNames", string.Join (",", usernames));
- DbParameter returnValue = AddParameter (command, null, ParameterDirection.ReturnValue, null);
- command.ExecuteNonQuery ();
- int retVal = GetReturnValue (returnValue);
- return retVal;
- }
- }
- public override ProfileInfoCollection FindInactiveProfilesByUserName (ProfileAuthenticationOption authenticationOption,
- string usernameToMatch,
- DateTime userInactiveSinceDate,
- int pageIndex,
- int pageSize,
- out int totalRecords)
- {
- CheckParam ("usernameToMatch", usernameToMatch, 256);
- if (pageIndex < 0)
- throw new ArgumentException("pageIndex is less than zero");
- if (pageSize < 1)
- throw new ArgumentException ("pageIndex is less than one");
- if (pageIndex * pageSize + pageSize - 1 > Int32.MaxValue)
- throw new ArgumentException ("pageIndex and pageSize are too large");
- using (DbConnection connection = CreateConnection ()) {
- DbCommand command = factory.CreateCommand ();
- command.Connection = connection;
- command.CommandType = CommandType.StoredProcedure;
- command.CommandText = @"aspnet_Profile_GetProfiles";
- AddParameter (command, "ApplicationName", ApplicationName);
- AddParameter (command, "ProfileAuthOptions", authenticationOption);
- AddParameter (command, "PageIndex", pageIndex);
- AddParameter (command, "PageSize", pageSize);
- AddParameter (command, "UserNameToMatch", usernameToMatch);
- AddParameter (command, "InactiveSinceDate", userInactiveSinceDate);
- using (DbDataReader reader = command.ExecuteReader ()) {
- return BuildProfileInfoCollection (reader, out totalRecords);
- }
- }
- }
- public override ProfileInfoCollection FindProfilesByUserName (ProfileAuthenticationOption authenticationOption,
- string usernameToMatch,
- int pageIndex,
- int pageSize,
- out int totalRecords)
- {
- CheckParam ("usernameToMatch", usernameToMatch, 256);
- if (pageIndex < 0)
- throw new ArgumentException ("pageIndex is less than zero");
- if (pageSize < 1)
- throw new ArgumentException ("pageIndex is less than one");
- if (pageIndex * pageSize + pageSize - 1 > Int32.MaxValue)
- throw new ArgumentException ("pageIndex and pageSize are too large");
- using (DbConnection connection = CreateConnection ()) {
- DbCommand command = factory.CreateCommand ();
- command.Connection = connection;
- command.CommandType = CommandType.StoredProcedure;
- command.CommandText = @"aspnet_Profile_GetProfiles";
- AddParameter (command, "ApplicationName", ApplicationName);
- AddParameter (command, "ProfileAuthOptions", authenticationOption);
- AddParameter (command, "PageIndex", pageIndex);
- AddParameter (command, "PageSize", pageSize);
- AddParameter (command, "UserNameToMatch", usernameToMatch);
- AddParameter (command, "InactiveSinceDate", null);
- using (DbDataReader reader = command.ExecuteReader ()) {
- return BuildProfileInfoCollection (reader, out totalRecords);
- }
- }
- }
- public override ProfileInfoCollection GetAllInactiveProfiles (ProfileAuthenticationOption authenticationOption,
- DateTime userInactiveSinceDate,
- int pageIndex,
- int pageSize,
- out int totalRecords)
- {
- if (pageIndex < 0)
- throw new ArgumentException ("pageIndex is less than zero");
- if (pageSize < 1)
- throw new ArgumentException ("pageIndex is less than one");
- if (pageIndex * pageSize + pageSize - 1 > Int32.MaxValue)
- throw new ArgumentException ("pageIndex and pageSize are too large");
-
- using (DbConnection connection = CreateConnection ()) {
- DbCommand command = factory.CreateCommand ();
- command.Connection = connection;
- command.CommandType = CommandType.StoredProcedure;
- command.CommandText = @"aspnet_Profile_GetProfiles";
- AddParameter (command, "ApplicationName", ApplicationName);
- AddParameter (command, "ProfileAuthOptions", authenticationOption);
- AddParameter (command, "PageIndex", pageIndex);
- AddParameter (command, "PageSize", pageSize);
- AddParameter (command, "UserNameToMatch", null);
- AddParameter (command, "InactiveSinceDate", null);
- using (DbDataReader reader = command.ExecuteReader ()) {
- return BuildProfileInfoCollection (reader, out totalRecords);
- }
- }
- }
- public override ProfileInfoCollection GetAllProfiles (ProfileAuthenticationOption authenticationOption,
- int pageIndex,
- int pageSize,
- out int totalRecords)
- {
- if (pageIndex < 0)
- throw new ArgumentException ("pageIndex is less than zero");
- if (pageSize < 1)
- throw new ArgumentException ("pageIndex is less than one");
- if (pageIndex * pageSize + pageSize - 1 > Int32.MaxValue)
- throw new ArgumentException ("pageIndex and pageSize are too large");
- using (DbConnection connection = CreateConnection ()) {
- DbCommand command = factory.CreateCommand ();
- command.Connection = connection;
- command.CommandType = CommandType.StoredProcedure;
- command.CommandText = @"aspnet_Profile_GetProfiles";
- AddParameter (command, "ApplicationName", ApplicationName);
- AddParameter (command, "ProfileAuthOptions", authenticationOption);
- AddParameter (command, "PageIndex", pageIndex);
- AddParameter (command, "PageSize", pageSize);
- AddParameter (command, "UserNameToMatch", null);
- AddParameter (command, "InactiveSinceDate", null);
- using (DbDataReader reader = command.ExecuteReader ()) {
- return BuildProfileInfoCollection (reader, out totalRecords);
- }
- }
- }
- public override int GetNumberOfInactiveProfiles (ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
- {
- using (DbConnection connection = CreateConnection ()) {
- DbCommand command = factory.CreateCommand ();
- command.Connection = connection;
- command.CommandType = CommandType.StoredProcedure;
- command.CommandText = @"aspnet_Profile_GetNumberOfInactiveProfiles";
- AddParameter (command, "ApplicationName", ApplicationName);
- AddParameter (command, "ProfileAuthOptions", authenticationOption);
- AddParameter (command, "InactiveSinceDate", userInactiveSinceDate);
- int returnValue = 0;
- using (DbDataReader reader = command.ExecuteReader ()) {
- if (reader.Read ())
- returnValue = reader.GetInt32 (0);
- }
- return returnValue;
- }
- }
- public override SettingsPropertyValueCollection GetPropertyValues (SettingsContext sc, SettingsPropertyCollection properties)
- {
- SettingsPropertyValueCollection settings = new SettingsPropertyValueCollection ();
- if (properties.Count == 0)
- return settings;
- foreach (SettingsProperty property in properties) {
- if (property.SerializeAs == SettingsSerializeAs.ProviderSpecific)
- if (property.PropertyType.IsPrimitive || property.PropertyType == typeof (String))
- property.SerializeAs = SettingsSerializeAs.String;
- else
- property.SerializeAs = SettingsSerializeAs.Xml;
- settings.Add (new SettingsPropertyValue (property));
- }
- string username = (string) sc ["UserName"];
- using (DbConnection connection = CreateConnection ()) {
- DbCommand command = factory.CreateCommand ();
- command.Connection = connection;
- command.CommandType = CommandType.StoredProcedure;
- command.CommandText = @"aspnet_Profile_GetProperties";
- AddParameter (command, "ApplicationName", ApplicationName);
- AddParameter (command, "UserName", username);
- AddParameter (command, "CurrentTimeUtc", DateTime.UtcNow);
- using (DbDataReader reader = command.ExecuteReader ()) {
- if (reader.Read ()) {
- string allnames = reader.GetString (0);
- string allvalues = reader.GetString (1);
- int binaryLen = (int) reader.GetBytes (2, 0, null, 0, 0);
- byte [] binaryvalues = new byte [binaryLen];
- reader.GetBytes (2, 0, binaryvalues, 0, binaryLen);
- DecodeProfileData (allnames, allvalues, binaryvalues, settings);
- }
- }
- }
- return settings;
- }
-
- public override void SetPropertyValues (SettingsContext sc, SettingsPropertyValueCollection properties)
- {
- string username = (string) sc ["UserName"];
- bool isAnonymous = !(bool) sc ["IsAuthenticated"];
- string names = String.Empty;
- string values = String.Empty;
- byte [] buf = null;
- EncodeProfileData (ref names, ref values, ref buf, properties, !isAnonymous);
- using (DbConnection connection = CreateConnection ()) {
- DbCommand command = factory.CreateCommand ();
- command.Connection = connection;
- command.CommandType = CommandType.StoredProcedure;
- command.CommandText = @"aspnet_Profile_SetProperties";
- AddParameter (command, "ApplicationName", ApplicationName);
- AddParameter (command, "PropertyNames", names);
- AddParameter (command, "PropertyValuesString", values);
- AddParameter (command, "PropertyValuesBinary", buf);
- AddParameter (command, "UserName", username);
- AddParameter (command, "IsUserAnonymous", isAnonymous);
- AddParameter (command, "CurrentTimeUtc", DateTime.UtcNow);
- // Return value
- AddParameter (command, null, ParameterDirection.ReturnValue, null);
- command.ExecuteNonQuery ();
- return;
- }
- }
- public override void Initialize (string name, NameValueCollection config)
- {
- if (config == null)
- throw new ArgumentNullException ("config");
- base.Initialize (name, config);
- applicationName = GetStringConfigValue (config, "applicationName", "/");
- ProfileSection section = (ProfileSection) WebConfigurationManager.GetSection ("system.web/profile");
- string connectionStringName = config ["connectionStringName"];
- if (applicationName.Length > 256)
- throw new ProviderException ("The ApplicationName attribute must be 256 characters long or less.");
- if (connectionStringName == null || connectionStringName.Length == 0)
- throw new ProviderException ("The ConnectionStringName attribute must be present and non-zero length.");
- connectionString = WebConfigurationManager.ConnectionStrings [connectionStringName];
- factory = connectionString == null || String.IsNullOrEmpty (connectionString.ProviderName) ?
- System.Data.SqlClient.SqlClientFactory.Instance :
- ProvidersHelper.GetDbProviderFactory (connectionString.ProviderName);
- }
- public override string ApplicationName {
- get { return applicationName; }
- set { applicationName = value; }
- }
- DbConnection CreateConnection ()
- {
- DbConnection connection = factory.CreateConnection ();
- connection.ConnectionString = connectionString.ConnectionString;
- connection.Open ();
- return connection;
- }
- DbParameter AddParameter (DbCommand command, string parameterName, object parameterValue)
- {
- return AddParameter (command, parameterName, ParameterDirection.Input, parameterValue);
- }
- DbParameter AddParameter (DbCommand command, string parameterName, ParameterDirection direction, object parameterValue)
- {
- DbParameter dbp = command.CreateParameter ();
- dbp.ParameterName = parameterName;
- dbp.Value = parameterValue;
- dbp.Direction = direction;
- command.Parameters.Add (dbp);
- return dbp;
- }
- void CheckParam (string pName, string p, int length)
- {
- if (p == null)
- throw new ArgumentNullException (pName);
- if (p.Length == 0 || p.Length > length || p.IndexOf (",") != -1)
- throw new ArgumentException (String.Format ("invalid format for {0}", pName));
- }
-
- static int GetReturnValue (DbParameter returnValue)
- {
- object value = returnValue.Value;
- return value is int ? (int) value : -1;
- }
- private ProfileInfo ReadProfileInfo (DbDataReader reader)
- {
- ProfileInfo pi = null;
- try {
- string username = reader.GetString (0);
- bool anonymous = reader.GetBoolean (1);
- DateTime lastUpdate = reader.GetDateTime (2);
- DateTime lastActivity = reader.GetDateTime (3);
- int size = reader.GetInt32 (4);
- pi = new ProfileInfo (username, anonymous, lastActivity, lastUpdate, size);
- }
- catch {
- }
- return pi;
- }
- private ProfileInfoCollection BuildProfileInfoCollection (DbDataReader reader, out int totalRecords)
- {
- ProfileInfoCollection pic = new ProfileInfoCollection ();
- while (reader.Read ()) {
- ProfileInfo pi = ReadProfileInfo (reader);
- if (pi != null)
- pic.Add (pi);
- }
- totalRecords = 0;
- if (reader.NextResult ()) {
- if (reader.Read ())
- totalRecords = reader.GetInt32 (0);
- }
- return pic;
- }
- string GetStringConfigValue (NameValueCollection config, string name, string def)
- {
- string retVal = def;
- string val = config [name];
- if (val != null)
- retVal = val;
- return retVal;
- }
- // Helper methods
- private void DecodeProfileData (string allnames, string values, byte [] buf, SettingsPropertyValueCollection properties)
- {
- if (allnames == null || values == null || buf == null || properties == null)
- return;
- string [] names = allnames.Split (':');
- for (int i = 0; i < names.Length; i += 4) {
- string name = names [i];
- SettingsPropertyValue pp = properties [name];
- if (pp == null)
- continue;
- int pos = Int32.Parse (names [i + 2], CultureInfo.InvariantCulture);
- int len = Int32.Parse (names [i + 3], CultureInfo.InvariantCulture);
- if (len == -1 && !pp.Property.PropertyType.IsValueType) {
- pp.PropertyValue = null;
- pp.IsDirty = false;
- pp.Deserialized = true;
- }
- else if (names [i + 1] == "S" && pos >= 0 && len > 0 && values.Length >= pos + len) {
- pp.SerializedValue = values.Substring (pos, len);
- }
- else if (names [i + 1] == "B" && pos >= 0 && len > 0 && buf.Length >= pos + len) {
- byte [] buf2 = new byte [len];
- Buffer.BlockCopy (buf, pos, buf2, 0, len);
- pp.SerializedValue = buf2;
- }
- }
- }
- private void EncodeProfileData (ref string allNames, ref string allValues, ref byte [] buf, SettingsPropertyValueCollection properties, bool userIsAuthenticated)
- {
- StringBuilder names = new StringBuilder ();
- StringBuilder values = new StringBuilder ();
- MemoryStream stream = new MemoryStream ();
- try {
- foreach (SettingsPropertyValue pp in properties) {
- if (!userIsAuthenticated && !(bool) pp.Property.Attributes ["AllowAnonymous"])
- continue;
- if (!pp.IsDirty && pp.UsingDefaultValue)
- continue;
- int len = 0, pos = 0;
- string propValue = null;
- if (pp.Deserialized && pp.PropertyValue == null)
- len = -1;
- else {
- object sVal = pp.SerializedValue;
- if (sVal == null)
- len = -1;
- else if (sVal is string) {
- propValue = (string) sVal;
- len = propValue.Length;
- pos = values.Length;
- }
- else {
- byte [] b2 = (byte []) sVal;
- pos = (int) stream.Position;
- stream.Write (b2, 0, b2.Length);
- stream.Position = pos + b2.Length;
- len = b2.Length;
- }
- }
- names.Append (pp.Name + ":" + ((propValue != null) ? "S" : "B") + ":" + pos.ToString (CultureInfo.InvariantCulture) + ":" + len.ToString (CultureInfo.InvariantCulture) + ":");
- if (propValue != null)
- values.Append (propValue);
- }
- buf = stream.ToArray ();
- }
- finally {
- if (stream != null)
- stream.Close ();
- }
- allNames = names.ToString ();
- allValues = values.ToString ();
- }
- }
- }
- #endif
|