Introduction
One of the requirements of the project I work on is that, "the admin should be able to mark a user as inactive, so the user would not be able to access the application anymore even if he is currently logged in". First, I thought that this would not be possible, but later on, I found this graat article by Robert Boedigheimer, which suggested the use of a custom base class, which brought to me an entire new horizon on how to tackle the two most important parts of writing .NET web based applications - security and memory management.
Using the code
Derive your page from the base class. In the code-behind file, use:
public partial class MyImportantPage : CustomBasePage
Thus, your pages will have all the properties of the System.Web.UI.Page
class plus those you have defined in your base class. The second advantage of this class is Session management. Let us assume that you have 1 GB of RAM on your Web server. What would happen if you retrieve a couple of datasets per page (1 MB each)? Your Session expiration time is 30 minutes and the number of on-line users is close to 600 ... Well, with those simulated numbers, with the default settings, the IIS will perform a memory cleaning and throw all the users out ...
In reality, most of the variables set as Session variables do not need to be global, but are page-specific... Somebody might argue to use ViewState for those variables - well, watch the performance after setting a dataset with a 1 MB size ... the ViewState should only be used for small variables. Another option is to use the Cache ... My experience is that the Cache is unreliable - you cannot be 100% sure what the client browser will do to your important objects stored, yet your code rules the server ...
When you would like to set a variable which is to be used globally (e.g., the variable will persist through the time of the current session of the user, even if the user leaves the current page), set the variable like so:
string StrGlobalVariable = Session [ "global.StrGlobalVariable" ];
When you would like to use a variable only in the scope of the page (e.g., the variable will be deleted once the user requests a different page), set the variable as follows:
string StrPageVariable = Session [ base.PageName + ".PageVariable" ] ;
So, here is the code (read the comments carefully):
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Collections.Generic;
using System.Text;
public class CustomBasePage : System.Web.UI.Page
{
private string pageName;
#region Properties
public string PageName
{
get
{
return System.IO.Path.GetFileNameWithoutExtension (
System.Web.HttpContext.Current.Request.Url.AbsolutePath );
}
set { pageName = value; }
}
#endregion
public CustomBasePage ()
{
}
override protected void OnInit ( EventArgs e )
{
base.OnInit ( e );
#region Introduction
string msg;
string baseDir;
string pageName;
#endregion
#region Instantiation
pageName = System.IO.Path.GetFileNameWithoutExtension (
System.Web.HttpContext.Current.Request.Url.AbsolutePath );
if (HttpContext.Current.Session != null)
{
if (HttpContext.Current.Session.IsNewSession)
{
string szCookieHeader = Request.Headers [ "Cookie" ];
if (( null != szCookieHeader ) &&
( szCookieHeader.IndexOf ( "ASP.NET_SessionId" ) >= 0 ))
{
HttpContext.Current.Session [ "global.msg" ] =
" No action has been performed in " +
"the last 15 minutes, please login again";
Response.Redirect ( "~/login.aspx" );
}
}
}
if (Session [ "global.LOGINISOK" ] == null ||
System.Convert.ToString (
Session [ "global.LOGINISOK" ] ).Equals ( "LOGINISOK" ) == false)
{
Utils.Debugger.WriteIf ( Session [ "global.Domain_Name" ] +
" redirecting to login page !!!: \n" );
Session [ "global.msg" ] =
"Welcome to the My Application name ! Please, login first ";
Response.Redirect ( "~/login.aspx" );
}
else
{
ClearAllNonGlobalSessionsButMine ();
}
}
private void ClearAllNonGlobalSessionsButMine ()
{
string fileNameNoExt = System.IO.Path.GetFileNameWithoutExtension (
System.Web.HttpContext.Current.Request.Url.AbsolutePath );
for (int i = 0; i< HttpContext.Current.Session.Count; i++)
{
string keyValue = HttpContext.Current.Session.Keys [ i ];
if (keyValue.Contains ( fileNameNoExt ) || keyValue.Contains ( "global" ))
{ ; }
else
{
HttpContext.Current.Session [ HttpContext.Current.Session.Keys [ i ] ] = null;
}
}
}
public void ClearAllNonGlobalSessionsAndMine ()
{
string fileNameNoExt = System.IO.Path.GetFileNameWithoutExtension (
System.Web.HttpContext.Current.Request.Url.AbsolutePath );
for (int i = 0; i< HttpContext.Current.Session.Count; i++)
{
string keyValue = HttpContext.Current.Session.Keys [ i ];
if (keyValue.Contains ( "global" ))
{ ; }
else
{
HttpContext.Current.Session [ HttpContext.Current.Session.Keys [ i ] ] = null;
}
}
}
}
I almost noticed, you wandered what the DebugPage
method is. Here it is:
using System;
using System.Text.RegularExpressions;
using System.Data;
using System.Web.UI.WebControls;
namespace Utils
{
public class Debugger
public static void DebugPage ( System.Web.UI.Page page )
{
string baseDirLocal = System.Web.HttpContext.Current.Server.MapPath ( "~" );
Regex Remover = new Regex ( @"^.*(\\|\/)(.*)$",
RegexOptions.IgnoreCase | RegexOptions.Compiled );
string bareDir = Remover.Replace ( baseDirLocal , "$2" );
string strToRemoveAtEnd= System.Web.HttpContext.Current.Request.Url.AbsolutePath;
char [] charsToRemoveAtEnd = strToRemoveAtEnd.ToCharArray ();
string baseDir = System.Web.HttpContext.Current.Request.Url.AbsoluteUri;
baseDir = baseDir.TrimEnd ( charsToRemoveAtEnd );
baseDir = baseDir + "/" + bareDir + "/";
WriteIf("The basedir of the project locally is " +
"HttpContext.Current.Server.MapPath(\"~/\");" +
System.Web.HttpContext.Current.Server.MapPath ( "~" ) );
WriteIf ( "The basedir of the project locally is " +
"AppDomain.CurrentDomain.BaseDirectory;" +
AppDomain.CurrentDomain.BaseDirectory);
WriteIf ( "The virtual path of this page " +
"( System.Web.HttpContext.Current.Request.PathInfo) is " +
System.Web.HttpContext.Current.Request.PathInfo ) ;
WriteIf ( "System.IO.Path.GetFileName (" +
" System.Web.HttpContext.Current.Request.Url.AbsolutePath ) -- " +
System.IO.Path.GetFileName (
System.Web.HttpContext.Current.Request.Url.AbsolutePath ) );
WriteIf ( "System.Web.HttpContext.Current.Request.Url.AbsolutePath -- " +
System.Web.HttpContext.Current.Request.Url.AbsolutePath );
WriteIf ( "System.Web.HttpContext.Current.Request.Url.AbsoluteUri -- " +
System.Web.HttpContext.Current.Request.Url.AbsoluteUri );
WriteIf ( "System.Web.HttpContext.Current.Request.Url.DnsSafeHost -- " +
System.Web.HttpContext.Current.Request.Url.DnsSafeHost );
WriteIf ( "System.Web.HttpContext.Current.Request.Url.Fragment -- " +
System.Web.HttpContext.Current.Request.Url.Fragment );
WriteIf ( "System.Web.HttpContext.Current.Request.Url.Host -- " +
System.Web.HttpContext.Current.Request.Url.Host ) ;
WriteIf ( "System.Web.HttpContext.Current.Request.Url.HostNameType -- " +
System.Web.HttpContext.Current.Request.Url.HostNameType ) ;
WriteIf ( "System.Web.HttpContext.Current.Request.Url.LocalPath -- " +
System.Web.HttpContext.Current.Request.Url.LocalPath ) ;
WriteIf ( "System.Web.HttpContext.Current.Request.Url.OriginalString -- " +
System.Web.HttpContext.Current.Request.Url.OriginalString ) ;
WriteIf ( "System.Web.HttpContext.Current.Request.Url.PathAndQuery -- " +
System.Web.HttpContext.Current.Request.Url.PathAndQuery ) ;
WriteIf ( "System.Web.HttpContext.Current.Request.Url.Scheme -- " +
System.Web.HttpContext.Current.Request.Url.Scheme ) ;
WriteIf ( "System.Web.HttpContext.Current.Request.Url.Segments.ToString () -- " +
System.Web.HttpContext.Current.Request.Url.Segments.ToString () );
WriteIf ( "System.Web.HttpContext.Current.Request.Url.UserInfo -- " +
System.Web.HttpContext.Current.Request.Url.UserInfo );
WriteIf ( "System.Web.HttpContext.Current.Request.ServerVariables[ \"HTTP_COOKIE\" ] is " +
System.Web.HttpContext.Current.Request.ServerVariables [ "HTTP_COOKIE" ] );
}
public static void WriteIf ( string msg )
{
System.Diagnostics.Debug.WriteIf ( System.Convert.ToBoolean
( System.Configuration.ConfigurationSettings.AppSettings [ "Debugging" ] ) ,
DateTime.Now.ToString ( "yyyy:MM:dd -- hh:mm:ss.fff --- " ) + msg + "\n" );
}
}
}
Points of interest
If you have carefully read the code, now you know where to put your code for implementing the requirement I presented above. If you are still having difficulties figuring out, put a comment below, and I will spare more time for writing an article about it ...