johnllao

July 9, 2009

Generic method for Sorting Collection

Filed under: Uncategorized — johnllao @ 5:43 pm

In this blog I would like to show a code perform sorting from a generic collection of type List<T>. This code has been always in my utility classes I used from most of my projects.

Also in the following codes I demonstrated the CompareFields function that can perform Compare operations to any promitive types in .Net CLR

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="field_name"></param>
        /// <param name="mode"></param>
        /// <param name="item1"></param>
        /// <param name="item2"></param>
        /// <returns></returns>
        public static int CompareFields<T>(string field_name, string mode, T item1, T item2)
        {
            Type type = typeof(T);
            PropertyInfo property = type.GetProperty(field_name);
            MethodInfo compareMethod = property.PropertyType.GetMethod("CompareTo", new Type[] { typeof(object) });

            object v1 = property.GetValue(item1, null);
            object v2 = property.GetValue(item2, null);

            int r;
            if (mode == "A")
            {
                r = Convert.ToInt32(compareMethod.Invoke(v1, new object[] { v2 }));
            }
            else
            {
                r = Convert.ToInt32(compareMethod.Invoke(v2, new object[] { v1 }));
            }
            return r;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collection"></param>
        /// <param name="field_name"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static void SortCollection<T>(List<T> collection, string field_name, string mode)
        {
            collection.Sort(
                    delegate(T item1, T item2)
                    {
                        return CompareFields<T>(field_name, mode, item1, item2);
                    }
                );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collection"></param>
        /// <param name="field_name"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static void SortCollection<T>(List<T> collection, string field_name)
        {
            SortCollection<T>(collection, field_name, "A");
        }

July 8, 2009

Custom Sybase Database to persist Session state

Filed under: Uncategorized — johnllao @ 2:17 pm

In this blog I would like to share the SybaseSessionState I have implemented. Thanks to this article http://www.codeproject.com/KB/aspnet/ASPNET_session_in_MySql.aspx in CodeProject. I only did a slight changes to user Sybase as the data store.

 In your Web.config, you needed to use the following configuration.

    <sessionState cookieless="false" regenerateExpiredSessionId="true" mode="Custom" customProvider="SybaseSessionProvider" >
      <providers>
        <add name="SybaseSessionProvider"
             type="SybaseSessionStateStore"
             connectionStringName="YourConnectionStringName"
             writeExceptionsToEventLog="false" />
      </providers>
    </sessionState>

 Please see the code

    /// <summary>
    /// <remarks>
    /// The following table has to be created
    ///     CREATE TABLE sessions
    ///     (
    ///         SessionId       varchar(80)  NOT NULL,
    ///         ApplicationName varchar(255) NOT NULL,
    ///         Created         datetime     NOT NULL,
    ///         Expires         datetime     NOT NULL,
    ///         LockDate        datetime     NOT NULL,
    ///         LockId          int          NOT NULL,
    ///         Timeout         int          NOT NULL,
    ///         Locked          bit          NOT NULL,
    ///         SessionItems    text,
    ///         Flags           int          NOT NULL,
    ///         CONSTRAINT PKSessions PRIMARY KEY (SessionId, ApplicationName)
    ///      )
    /// </remarks>
    /// </summary>
    public sealed class SybaseSessionStateStore : SessionStateStoreProviderBase
    {
        private SessionStateSection pConfig = null;
        private string connectionString;
        private ConnectionStringSettings pConnectionStringSettings;
        private string eventSource = "SybaseSessionStateStore";
        private string eventLog = "Application";
        private string exceptionMessage = "An exception occurred. Please contact your administrator.";
        private string pApplicationName;

        private bool pWriteExceptionsToEventLog = false;
        /// <summary>
        /// If false, exceptions are thrown to the caller. If true, exceptions are written to the event log.
        /// </summary>
        public bool WriteExceptionsToEventLog
        {
            get { return pWriteExceptionsToEventLog; }
            set { pWriteExceptionsToEventLog = value; }
        }

        /// <summary>
        /// The ApplicationName property is used to differentiate sessions in the data source by application.
        /// </summary>
        public string ApplicationName
        {
            get { return pApplicationName; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="config"></param>
        public override void Initialize(string name, NameValueCollection config)
        {
            // Initialize values from web.config.
            if (config == null)
                throw new ArgumentNullException("config");

            if (name == null || name.Length == 0)
                name = "SybaseSessionStateStore";

            if (String.IsNullOrEmpty(config["description"]))
            {
                config.Remove("description");
                config.Add("description", "Sybase Session State Store provider");
            }

            // Initialize the abstract base class.
            base.Initialize(name, config);

            // Initialize the ApplicationName property.
            pApplicationName = System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;

            // Get <sessionState> configuration element.
            System.Configuration.Configuration cfg = WebConfigurationManager.OpenWebConfiguration(ApplicationName);
            pConfig = (SessionStateSection)cfg.GetSection("system.web/sessionState");

            // Initialize connection string.
            pConnectionStringSettings = ConfigurationManager.ConnectionStrings[config["connectionStringName"]];

            if (pConnectionStringSettings == null || pConnectionStringSettings.ConnectionString.Trim() == "")
            {
                throw new ProviderException("Connection string cannot be blank.");
            }

            connectionString = pConnectionStringSettings.ConnectionString;

            // Initialize WriteExceptionsToEventLog
            pWriteExceptionsToEventLog = false;

            if (config["writeExceptionsToEventLog"] != null)
            {
                if (config["writeExceptionsToEventLog"].ToUpper() == "TRUE")
                    pWriteExceptionsToEventLog = true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public override void Dispose()
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="expireCallback"></param>
        /// <returns></returns>
        public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback)
        {
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="id"></param>
        /// <param name="item"></param>
        /// <param name="lockId"></param>
        /// <param name="newItem"></param>
        public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
        {
            // Serialize the SessionStateItemCollection as a string.
            string sessItems = Serialize((SessionStateItemCollection)item.Items);

            AseConnection conn = new AseConnection(connectionString);
            AseCommand cmd;
            AseCommand deleteCmd = null;

            if (newItem)
            {
                // AseCommand to clear an existing expired session if it exists.
                deleteCmd = new AseCommand("DELETE FROM sessions WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND Expires < @Expires", conn);
                deleteCmd.Parameters.Add("@SessionId", AseDbType.VarChar, 80).Value = id;
                deleteCmd.Parameters.Add("@ApplicationName", AseDbType.VarChar, 255).Value = ApplicationName;
                deleteCmd.Parameters.Add("@Expires", AseDbType.DateTime).Value = DateTime.Now;

                // AseCommand to insert the new session item.
                cmd = new AseCommand("INSERT INTO sessions (SessionId, ApplicationName, Created, Expires, LockDate, LockId, Timeout, Locked, SessionItems, Flags) Values(@SessionId, @ApplicationName, @Created, @Expires, @LockDate, @LockId, @Timeout, @Locked, @SessionItems, @Flags)", conn);
                cmd.Parameters.Add("@SessionId", AseDbType.VarChar, 80).Value = id;
                cmd.Parameters.Add("@ApplicationName", AseDbType.VarChar, 255).Value = ApplicationName;
                cmd.Parameters.Add("@Created", AseDbType.DateTime).Value = DateTime.Now;
                cmd.Parameters.Add("@Expires", AseDbType.DateTime).Value = DateTime.Now.AddMinutes((Double)item.Timeout);
                cmd.Parameters.Add("@LockDate", AseDbType.DateTime).Value = DateTime.Now;
                cmd.Parameters.Add("@LockId", AseDbType.Integer).Value = 0;
                cmd.Parameters.Add("@Timeout", AseDbType.Integer).Value = item.Timeout;
                cmd.Parameters.Add("@Locked", AseDbType.Integer).Value = 0;
                cmd.Parameters.Add("@SessionItems", AseDbType.Text).Value = sessItems;
                cmd.Parameters.Add("@Flags", AseDbType.Integer).Value = 0;
            }
            else
            {
                // AseCommand to update the existing session item.
                cmd = new AseCommand("UPDATE sessions SET Expires = @Expires, SessionItems = @SessionItems, Locked = @Locked WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND LockId = @LockId", conn);
                cmd.Parameters.Add("@Expires", AseDbType.DateTime).Value = DateTime.Now.AddMinutes((Double)item.Timeout);
                cmd.Parameters.Add("@SessionItems", AseDbType.Text).Value = sessItems;
                cmd.Parameters.Add("@Locked", AseDbType.Integer).Value = 0;
                cmd.Parameters.Add("@SessionId", AseDbType.VarChar, 80).Value = id;
                cmd.Parameters.Add("@ApplicationName", AseDbType.VarChar, 255).Value = ApplicationName;
                cmd.Parameters.Add("@LockId", AseDbType.Integer).Value = lockId;
            }

            try
            {
                conn.Open();

                if (deleteCmd != null)
                    deleteCmd.ExecuteNonQuery();

                cmd.ExecuteNonQuery();
            }
            catch (AseException e)
            {
                if (WriteExceptionsToEventLog)
                {
                    WriteToEventLog(e, "SetAndReleaseItemExclusive");
                    throw new ProviderException(exceptionMessage);
                }
                else
                    throw e;
            }
            finally
            {
                conn.Close();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="id"></param>
        /// <param name="locked"></param>
        /// <param name="lockAge"></param>
        /// <param name="lockId"></param>
        /// <param name="actionFlags"></param>
        /// <returns></returns>
        public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags)
        {
            return GetSessionStoreItem(false, context, id, out locked, out lockAge, out lockId, out actionFlags);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="id"></param>
        /// <param name="locked"></param>
        /// <param name="lockAge"></param>
        /// <param name="lockId"></param>
        /// <param name="actionFlags"></param>
        /// <returns></returns>
        public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags)
        {
            return GetSessionStoreItem(true, context, id, out locked, out lockAge, out lockId, out actionFlags);
        }

        /// <summary>
        /// GetSessionStoreItem is called by both the GetItem and GetItemExclusive methods. GetSessionStoreItem retrieves the 
        /// session data from the data source. If the lockRecord parameter is true (in the case of GetItemExclusive), then GetSessionStoreItem 
        /// locks the record and sets a new LockId and LockDate.
        /// </summary>
        /// <param name="lockRecord"></param>
        /// <param name="context"></param>
        /// <param name="id"></param>
        /// <param name="locked"></param>
        /// <param name="lockAge"></param>
        /// <param name="lockId"></param>
        /// <param name="actionFlags"></param>
        /// <returns></returns>
        private SessionStateStoreData GetSessionStoreItem(bool lockRecord, HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags)
        {
            // Initial values for return value and out parameters.
            SessionStateStoreData item = null;
            lockAge = TimeSpan.Zero;
            lockId = null;
            locked = false;
            actionFlags = 0;

            AseConnection conn = new AseConnection(connectionString);
            AseCommand cmd = null;
            AseDataReader reader = null;

            // Datetime to check if current session item is expired.
            DateTime expires;

            // String to hold serialized SessionStateItemCollection.
            string serializedItems = "";

            // True if a record is found in the database.
            bool foundRecord = false;

            // True if the returned session item is expired and needs to be deleted.
            bool deleteData = false;

            // Timeout value from the data store.
            int timeout = 0;

            try
            {
                conn.Open();

                // lockRecord is true when called from GetItemExclusive and  false when called from GetItem. 
                // Obtain a lock if possible. Ignore the record if it is expired.
                if (lockRecord)
                {
                    cmd = new AseCommand("UPDATE sessions SET Locked = @Locked1, LockDate = @LockDate WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND Locked = @Locked2 AND Expires > @Expires", conn);
                    cmd.Parameters.Add("@Locked1", AseDbType.Integer).Value = 1;
                    cmd.Parameters.Add("@LockDate", AseDbType.DateTime).Value = DateTime.Now;
                    cmd.Parameters.Add("@SessionId", AseDbType.VarChar, 80).Value = id;
                    cmd.Parameters.Add("@ApplicationName", AseDbType.VarChar, 255).Value = ApplicationName;
                    cmd.Parameters.Add("@Locked2", AseDbType.Integer).Value = 0;
                    cmd.Parameters.Add("@Expires", AseDbType.DateTime).Value = DateTime.Now;

                    if (cmd.ExecuteNonQuery() == 0)
                    {
                        // No record was updated because the record was locked or not found.
                        locked = true;
                    }
                    else
                    {
                        // The record was updated.
                        locked = false;
                    }
                }

                // Retrieve the current session item information.
                cmd = new AseCommand("SELECT Expires, SessionItems, LockId, LockDate, Flags, Timeout FROM sessions WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName", conn);
                cmd.Parameters.Add("@SessionId", AseDbType.VarChar, 80).Value = id;
                cmd.Parameters.Add("@ApplicationName", AseDbType.VarChar, 255).Value = ApplicationName;

                // Retrieve session item data from the data source.
                reader = cmd.ExecuteReader(CommandBehavior.SingleRow);
                while (reader.Read())
                {
                    expires = reader.GetDateTime(0);

                    if (expires < DateTime.Now)
                    {
                        // The record was expired. Mark it as not locked.
                        locked = false;
                        // The session was expired. Mark the data for deletion.
                        deleteData = true;
                    }
                    else
                        foundRecord = true;

                    serializedItems = reader.GetString(1);
                    lockId = reader.GetInt32(2);
                    lockAge = DateTime.Now.Subtract(reader.GetDateTime(3));
                    actionFlags = (SessionStateActions)reader.GetInt32(4);
                    timeout = reader.GetInt32(5);
                }
                reader.Close();

                // If the returned session item is expired, 
                // delete the record from the data source.
                if (deleteData)
                {
                    cmd = new AseCommand("DELETE FROM sessions WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName", conn);
                    cmd.Parameters.Add("@SessionId", AseDbType.VarChar, 80).Value = id;
                    cmd.Parameters.Add("@ApplicationName", AseDbType.VarChar, 255).Value = ApplicationName;

                    cmd.ExecuteNonQuery();
                }

                // The record was not found. Ensure that locked is false.
                if (!foundRecord)
                    locked = false;

                // If the record was found and you obtained a lock, then set 
                // the lockId, clear the actionFlags,
                // and create the SessionStateStoreItem to return.
                if (foundRecord && !locked)
                {
                    lockId = (int)lockId + 1;

                    cmd = new AseCommand("UPDATE sessions SET LockId = @LockId, Flags = 0 WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName", conn);
                    cmd.Parameters.Add("@LockId", AseDbType.Integer).Value = lockId;
                    cmd.Parameters.Add("@SessionId", AseDbType.VarChar, 80).Value = id;
                    cmd.Parameters.Add("@ApplicationName", AseDbType.VarChar, 255).Value = ApplicationName;

                    cmd.ExecuteNonQuery();

                    // If the actionFlags parameter is not InitializeItem, 
                    // deserialize the stored SessionStateItemCollection.
                    if (actionFlags == SessionStateActions.InitializeItem)
                        item = CreateNewStoreData(context, pConfig.Timeout.Minutes);
                    else
                        item = Deserialize(context, serializedItems, timeout);
                }
            }
            catch (AseException e)
            {
                if (WriteExceptionsToEventLog)
                {
                    WriteToEventLog(e, "GetSessionStoreItem");
                    throw new ProviderException(exceptionMessage);
                }
                else
                    throw e;
            }
            finally
            {
                if (reader != null) { reader.Close(); }
                conn.Close();
            }

            return item;
        }

        /// <summary>
        /// Serialize is called by the SetAndReleaseItemExclusive method to convert the SessionStateItemCollection into a Base64 string to 
        /// be stored in an Access Memo field.
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        private string Serialize(SessionStateItemCollection items)
        {
            MemoryStream ms = new MemoryStream();
            BinaryWriter writer = new BinaryWriter(ms);

            if (items != null)
                items.Serialize(writer);

            writer.Close();

            return Convert.ToBase64String(ms.ToArray());
        }

        /// <summary>
        /// DeSerialize is called by the GetSessionStoreItem method to convert the Base64 string stored in the Access Memo field to a 
        /// SessionStateItemCollection.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="serializedItems"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        private SessionStateStoreData Deserialize(HttpContext context, string serializedItems, int timeout)
        {
            MemoryStream ms = new MemoryStream(Convert.FromBase64String(serializedItems));

            SessionStateItemCollection sessionItems = new SessionStateItemCollection();

            if (ms.Length > 0)
            {
                BinaryReader reader = new BinaryReader(ms);
                sessionItems = SessionStateItemCollection.Deserialize(reader);
            }

            return new SessionStateStoreData(sessionItems,
              SessionStateUtility.GetSessionStaticObjects(context),
              timeout);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="id"></param>
        /// <param name="lockId"></param>
        public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
        {
            AseConnection conn = new AseConnection(connectionString);
            AseCommand cmd = new AseCommand("UPDATE sessions SET Locked = 0, Expires = @Expires WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND LockId = @LockId", conn);
            cmd.Parameters.Add("@Expires", AseDbType.DateTime).Value = DateTime.Now.AddMinutes(pConfig.Timeout.Minutes);
            cmd.Parameters.Add("@SessionId", AseDbType.VarChar, 80).Value = id;
            cmd.Parameters.Add("@ApplicationName", AseDbType.VarChar, 255).Value = ApplicationName;
            cmd.Parameters.Add("@LockId", AseDbType.Integer).Value = lockId;

            try
            {
                conn.Open();
                cmd.ExecuteNonQuery();
            }
            catch (AseException e)
            {
                if (WriteExceptionsToEventLog)
                {
                    WriteToEventLog(e, "ReleaseItemExclusive");
                    throw new ProviderException(exceptionMessage);
                }
                else
                    throw e;
            }
            finally
            {
                conn.Close();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="id"></param>
        /// <param name="lockId"></param>
        /// <param name="item"></param>
        public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
        {
            AseConnection conn = new AseConnection(connectionString);
            AseCommand cmd = new AseCommand("DELETE FROM sessions WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND LockId = @LockId", conn);
            cmd.Parameters.Add("@SessionId", AseDbType.VarChar, 80).Value = id;
            cmd.Parameters.Add("@ApplicationName", AseDbType.VarChar, 255).Value = ApplicationName;
            cmd.Parameters.Add("@LockId", AseDbType.Integer).Value = lockId;

            try
            {
                conn.Open();
                cmd.ExecuteNonQuery();
            }
            catch (AseException e)
            {
                if (WriteExceptionsToEventLog)
                {
                    WriteToEventLog(e, "RemoveItem");
                    throw new ProviderException(exceptionMessage);
                }
                else
                    throw e;
            }
            finally
            {
                conn.Close();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="id"></param>
        /// <param name="timeout"></param>
        public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            AseConnection conn = new AseConnection(connectionString);
            AseCommand cmd = new AseCommand("INSERT INTO sessions (SessionId, ApplicationName, Created, Expires, LockDate, LockId, Timeout, Locked, SessionItems, Flags) Values(@SessionId, @ApplicationName, @Created, @Expires, @LockDate, @LockId, @Timeout, @Locked, @SessionItems, @Flags)", conn);
            cmd.Parameters.Add("@SessionId", AseDbType.VarChar, 80).Value = id;
            cmd.Parameters.Add("@ApplicationName", AseDbType.VarChar, 255).Value = ApplicationName;
            cmd.Parameters.Add("@Created", AseDbType.DateTime).Value = DateTime.Now;
            cmd.Parameters.Add("@Expires", AseDbType.DateTime).Value = DateTime.Now.AddMinutes((Double)timeout);
            cmd.Parameters.Add("@LockDate", AseDbType.DateTime).Value = DateTime.Now;
            cmd.Parameters.Add("@LockId", AseDbType.Integer).Value = 0;
            cmd.Parameters.Add("@Timeout", AseDbType.Integer).Value = timeout;
            cmd.Parameters.Add("@Locked", AseDbType.Integer).Value = 0;
            cmd.Parameters.Add("@SessionItems", AseDbType.Text).Value = "";
            cmd.Parameters.Add("@Flags", AseDbType.Integer).Value = 1;

            try
            {
                conn.Open();
                cmd.ExecuteNonQuery();
            }
            catch (AseException e)
            {
                if (WriteExceptionsToEventLog)
                {
                    WriteToEventLog(e, "CreateUninitializedItem");
                    throw new ProviderException(exceptionMessage);
                }
                else
                    throw e;
            }
            finally
            {
                conn.Close();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
        {
            return new SessionStateStoreData(new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), timeout);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="id"></param>
        public override void ResetItemTimeout(HttpContext context,
                                              string id)
        {
            AseConnection conn = new AseConnection(connectionString);
            AseCommand cmd = new AseCommand("UPDATE sessions SET Expires = @Expires WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName", conn);
            cmd.Parameters.Add("@Expires", AseDbType.DateTime).Value = DateTime.Now.AddMinutes(pConfig.Timeout.Minutes);
            cmd.Parameters.Add("@SessionId", AseDbType.VarChar, 80).Value = id;
            cmd.Parameters.Add("@ApplicationName", AseDbType.VarChar, 255).Value = ApplicationName;

            try
            {
                conn.Open();
                cmd.ExecuteNonQuery();
            }
            catch (AseException e)
            {
                if (WriteExceptionsToEventLog)
                {
                    WriteToEventLog(e, "ResetItemTimeout");
                    throw new ProviderException(exceptionMessage);
                }
                else
                    throw e;
            }
            finally
            {
                conn.Close();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        public override void InitializeRequest(HttpContext context)
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        public override void EndRequest(HttpContext context)
        {
        }

        /// <summary>
        /// WriteToEventLog
        /// This is a helper function that writes exception detail to the event log. Exceptions are written to the event log as a security
        /// measure to ensure private database details are not returned to browser. If a method does not return a status or Boolean
        /// indicating the action succeeded or failed, the caller also throws a generic exception.
        /// </summary>
        /// <param name="e"></param>
        /// <param name="action"></param>
        private void WriteToEventLog(Exception e, string action)
        {
            EventLog log = new EventLog();
            log.Source = eventSource;
            log.Log = eventLog;

            string message = "An exception occurred communicating with the data source.\n\n";
            message += "Action: " + action + "\n\n";
            message += "Exception: " + e.ToString();

            log.WriteEntry(message);
        }
    }

July 6, 2009

Using WScript to get user name and domain name in IE

Filed under: Uncategorized — johnllao @ 10:37 am

The following codes show how to retrieve the user name and domain name from javascript code. The follwoing code is quite straight forward however a developer has to consider the following before using this code.

  • The code uses the built-in ActiveX object of IE which of course will only work for IE browsers.
  • Some browser security policies may not allow this implementation as this requires trust settings

    <form id="DefaultForm" runat="server">
        Authenticating user. Please wait...
        <input type="hidden" id="UserName" name="UserName" /><input type="hidden" id="Domain" name="Domain" />
        <script type="text/javascript">//<!--
            var netw = new ActiveXObject("WScript.Network");
            window.document.DefaultForm.UserName.value = netw.UserName;
            window.document.DefaultForm.Domain.value = netw.UserDomain;
            window.document.DefaultForm.submit();
        //-->
        </script>
    </form>

June 30, 2009

Manipulating Local User Accounts

Filed under: Uncategorized — johnllao @ 11:17 pm

In this blog I wil show some easy codes to Create, and manipulate a local user account. In my code I will be utilising the WinNT provider.

Creating a local user account

string username = UserNameTextBox.Text;
string password = PasswordTextBox.Text;

try
{
    DirectoryEntry localAd = new DirectoryEntry("WinNT://" + Environment.MachineName);
    DirectoryEntry user = localAd.Children.Add(username, "user");
    user.Invoke("SetPassword", new object[] { password });
    user.Invoke("Put", new object[] { "Description", password });
    user.Invoke("Put", new object[] { "FullName", "You are " + username });
    user.CommitChanges();

}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

On this code I have shown a simple way to create a local user account. Here we user the Invoke to call a method thru reflection from the underlying WinNT provider.

Changing password

string username = UserNameTextBox.Text;
string password = PasswordTextBox.Text;

try
{
    DirectoryEntry user = new DirectoryEntry("WinNT://" + Environment.MachineName + "/" + username);
    if (user != null)
    {
        user.Invoke("SetPassword", new object[] { password });
        user.Invoke("Put", new object[] { "Description", password });
        user.Invoke("Put", new object[] { "FullName", "You are " + username });
        user.CommitChanges();
    }
}
catch (Exception ex)
{
     MessageBox.Show(ex.Message);
}

This code is similar to the creation of user excep that the expression user from the provider is slightly different. Here we used the syntax WinNT://<server name>/<user name> to further filter our query toget the user name information. Alternatively, you can also implement the first code however you neede to use the Find function to get the user information.

Disabling an account

string username = UserNameTextBox.Text;
string password = PasswordTextBox.Text;

try
{
    DirectoryEntry user = new DirectoryEntry("WinNT://" + Environment.MachineName + "/" + username);
    if (user != null)
    {
        user.Properties["UserFlags"].Value = Convert.ToInt32(user.Properties["UserFlags"].Value) | 2;
        user.CommitChanges();
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

To disable a user account just user the “| 2″ expression against the existing value of the UserFlags. To enable it back just use the “& ~2″ expression against the existing value of the UserFlags (e.g. user.Properties["UserFlags"].Value = Convert.ToInt32(user.Properties["UserFlags"].Value) & ~2).

That’s it. Happy coding…

June 21, 2009

Using WcfPortal

Filed under: Uncategorized — johnllao @ 10:25 am

As we are all aware DataPortal in CSLA serves as the backbone in implemeting SOA in CSLA. This allows our application business objects to be hosted in other server. The beauty of implementing this in CSLA is that no code change needed to be done in our business object.  In this blog I will show how this can be achieved using a WCF hosted in IIS.

First this to do is to create a .svc file in your web project. In our case we will name our .svc file as WcfPortal.svc.

<%@ ServiceHost Language="C#" Debug="false" Service="Csla.Server.Hosts.WcfPortal" %>

As you can see, the value of service attribute is set to Csla.Server.Hosts.WcfPortal.

Next step is to set the following configuration in the web.config of your web project.

  <system.serviceModel>
    <bindings>
      <wsHttpBinding>

        <binding name="wsHttpBindingSettings"
                 closeTimeout="00:10:00"
                 openTimeout="00:10:00"
                 sendTimeout="00:10:00"
                 maxReceivedMessageSize="2147483647"
                 maxBufferPoolSize="2147483647"
                 messageEncoding="Text" >

          <readerQuotas maxDepth="2147483647"
                        maxStringContentLength="2147483647"
                        maxArrayLength="2147483647"
                        maxBytesPerRead="2147483647"
                        maxNameTableCharCount="2147483647" />

        </binding>

      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WcfPortalBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="Csla.Server.Hosts.WcfPortal" behaviorConfiguration="WcfPortalBehavior" >
        <endpoint address="" binding="wsHttpBinding" contract="Csla.Server.Hosts.IWcfPortal" bindingConfiguration="wsHttpBindingSettings" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>

One of the most important stuff to check is the bindingConfiguration settings, in our example we set the value of the maxReceivedMessageSize to a very big value. this is to avoid exceptions regarding the limit of the size of the message sent across the channel. Due to the size of your business object some scenarios may exceed the default size set by Wcf.

On the client machine se the following configurations

  <system.serviceModel>
    <bindings>
      <wsHttpBinding>

        <binding name="wsHttpBindingSettings"
                 closeTimeout="00:10:00"
                 openTimeout="00:10:00"
                 sendTimeout="00:10:00"
                 maxReceivedMessageSize="2147483647"
                 maxBufferPoolSize="2147483647"
                 messageEncoding="Text" >

          <readerQuotas maxDepth="2147483647"
                        maxStringContentLength="2147483647"
                        maxArrayLength="2147483647"
                        maxBytesPerRead="2147483647"
                        maxNameTableCharCount="2147483647" />

        </binding>

      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint name="WcfDataPortal"
                address="http://localhost:52423/WcfPortal.svc"
                binding="wsHttpBinding"
                contract="Csla.Server.Hosts.IWcfPortal"
                bindingConfiguration="wsHttpBindingSettings"/>
    </client>
  </system.serviceModel>

That’s it! Happy coding

June 5, 2009

Session_Start and Session_End event from custom HttpApplication

Filed under: Uncategorized — johnllao @ 7:23 pm

Example that shows how to assign Session_Start and Session_End events from a custom HttpApplication object.

By default HttpApplication only contains events related to a particular request such as BeginRequest, so in order to initiate the Session_Start and Session_End event one has to get reference to the SessionStateModule. SessionStateModule is one of the HttpModule that was attached to a web application, this module handles the session management. SessionHttpModule is also a sealed class so we cannot inherit from it, so the only way to intercept the Session_Start and Session_End events is to get reference of this module.

Please see the code below.

    public class KyuApplication : System.Web.HttpApplication
    {
        public override void Init()
        {
            SessionStateModule session = Modules["Session"] as SessionStateModule;
            if (session != null)
            {
                session.Start += new EventHandler(Session_Start);
                session.End += new EventHandler(Session_End);
            }
        }

        private void Session_Start(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("Session_Start");
        }

        private void Session_End(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("Session_End");
        }
    }

June 2, 2009

Object Builder Sample

Filed under: Uncategorized — johnllao @ 2:07 pm

ObjectBuilder Sample

The following code shows a simple example to use the ObjectBuilder as an IOC / DI container. ObjectBuilder is a component of the Microsoft Enterprise Application Block it is also the backbone of the Unity DI.

using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Practices.ObjectBuilder;

namespace StudyObjectBuilder.ConsoleApplication
{
    /// <summary>
    /// 
    /// </summary>
    public class Program
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        public static void Main(string[] args)
        {
            Locator l = new Locator();
            l.Add(typeof(ILifetimeContainer), new LifetimeContainer());

            Builder b = new Builder();
            b.Strategies.Clear();
            b.Strategies.AddNew<CreationStrategy>(BuilderStage.Creation);
            b.Strategies.AddNew<TypeMappingStrategy>(BuilderStage.PreCreation);
            b.Strategies.AddNew<SingletonStrategy>(BuilderStage.PreCreation);
            b.Strategies.AddNew<PropertyReflectionStrategy>(BuilderStage.PreCreation);
            b.Strategies.AddNew<PropertySetterStrategy>(BuilderStage.Initialization);
            b.Strategies.AddNew<ConstructorReflectionStrategy>(BuilderStage.PreCreation);
            //b.Strategies.AddNew<MethodReflectionStrategy>(BuilderStage.PreCreation);
            //b.Strategies.AddNew<MethodExecutionStrategy>(BuilderStage.Initialization);
            //b.Strategies.AddNew<BuilderAwareStrategy>(BuilderStage.PostInitialization);

            b.Policies.SetDefault<ICreationPolicy>(new DefaultCreationPolicy());
            b.Policies.Set<ISingletonPolicy>(new SingletonPolicy(true), typeof(ConsoleLogger), null);
            b.Policies.Set<ITypeMappingPolicy>(new TypeMappingPolicy(typeof(TraceLogger), null), typeof(ILogger), null);

            ConsoleLogger logger = b.BuildUp<ConsoleLogger>(l, null, null);

            Person p = b.BuildUp<Person>(l, null, null);
            p.Id = 1;
            p.Name = "John";
            p.Greet();

            Person p2 = b.BuildUp<Person>(l, null, null);
            p2.Id = 2;
            p2.Name = "Bob";
            p2.Greet();

            Console.ReadLine();
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public class Person
    {
        private ILogger _logger;
        //[Microsoft.Practices.ObjectBuilder.Dependency(CreateType = typeof(ConsoleLogger))]
        //public ILogger Logger
        //{
        //    get { return _logger; }
        //    set { _logger = value; }
        //}

        private int _id;

        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }

        private string _name;

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="logger"></param>
        public Person([Microsoft.Practices.ObjectBuilder.Dependency(CreateType = typeof(ConsoleLogger))]ILogger logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 
        /// </summary>
        public void Greet()
        {
            _logger.Write("Hello " + _name);
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public interface ILogger
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        void Write(string message);
    }

    /// <summary>
    /// 
    /// </summary>
    public class TraceLogger : ILogger
    {

        public TraceLogger()
        {

        }

        #region ILogger Members
        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public void Write(string message)
        {
            System.Diagnostics.Trace.WriteLine(message);
        }

        #endregion
    }

    /// <summary>
    /// 
    /// </summary>
    public class ConsoleLogger : ILogger
    {

        public ConsoleLogger()
        {

        }

        #region ILogger Members
        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public void Write(string message)
        {
            Console.WriteLine(message);
        }

        #endregion
    }
}

October 31, 2008

Webservice Proxy Authentication

Filed under: Uncategorized — johnllao @ 5:12 pm

Here is a sample code that shows how to authenticate public web service request for proxy authenticated networks. The CountryProxy object I generated using wsdl.exe from http://www.webservicex.net/WCF/default.aspx

 

    /// <summary>
    /// 
    /// </summary>
    public class Program
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        public static void Main(string[] args)
        {
            WebProxy proxy = new WebProxy("proxy_address");
            proxy.Credentials = new NetworkCredential("username", "password", "domain"); ;

            Country cty = new Country();
            cty.Proxy = proxy;

            string countries = cty.GetCountries();
            Console.WriteLine(countries);

            Console.ReadLine();
        }
    }

October 12, 2008

Use of Arrays in .NET

Filed under: Uncategorized — johnllao @ 8:31 am

Got this cool articel about the use of arrays when programming in .net. Worth reading.

http://blogs.msdn.com/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx

September 12, 2008

Smile!

Filed under: Uncategorized — johnllao @ 5:27 pm

                          oooo$$$$$$$$$$$$oooo
                      oo$$$$$$$$$$$$$$$$$$$$$$$$o
                   oo$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o         o$   $$ o$
   o $ oo        o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o       $$ $$ $$o$
oo $ $ "$      o$$$$$$$$$    $$$$$$$$$$$$$    $$$$$$$$$o       $$$o$$o$
"$$$$$$o$     o$$$$$$$$$      $$$$$$$$$$$      $$$$$$$$$$o    $$$$$$$$
  $$$$$$$    $$$$$$$$$$$      $$$$$$$$$$$      $$$$$$$$$$$$$$$$$$$$$$$
  $$$$$$$$$$$$$$$$$$$$$$$    $$$$$$$$$$$$$    $$$$$$$$$$$$$$  """$$$
   "$$$""""$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     "$$$
    $$$   o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     "$$$o
   o$$"   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       $$$o
   $$$    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" "$$$$$$ooooo$$$$o
  o$$$oooo$$$$$  $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   o$$$$$$$$$$$$$$$$$
  $$$$$$$$"$$$$   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     $$$$""""""""
 """"       $$$$    "$$$$$$$$$$$$$$$$$$$$$$$$$$$$"      o$$$
            "$$$o     """$$$$$$$$$$$$$$$$$$"$$"         $$$
              $$$o          "$$""$$$$$$""""           o$$$
               $$$$o                                o$$$"
                "$$$$o      o$$$$$$o"$$$$o        o$$$$
                  "$$$$$oo     ""$$$$o$$$$$o   o$$$$""
                     ""$$$$$oooo  "$$$o$$$$$$$$$"""
                        ""$$$$$$$oo $$$$$$$$$$
                                """"$$$$$$$$$$$
                                    $$$$$$$$$$$$
                                     $$$$$$$$$$"
                                      "$$$""
Older Posts »

Blog at WordPress.com.