Wednesday, April 28, 2010

Prim and Proper way to ASP.NET Sessions

After being to the web domain, I felt a bit uneasy by the way Sessions were handled in ASP.NET; more or less the session class was like a universal adapter, where you can plug in data-types from primitive types to reference types. At first glance, it might seem like a boon, but the devil is in the details; as soon as the development phase scales up, this very handy feature could turn out to be a nightmare, if not properly dealt with.

Here I had compiled some common issues, while dealing with raw ASP.NET session objects.
  • Session Name Typo - This is a common issue, where a session name say "AutomationID" created in PageA.aspx when accessed from PageB.aspx, might be inaccessible due to session name typo, when a developer accesses the session, by keying in "Aut0mationID". Here you can find a small typo, where zero is entered in, instead of the character "o". These sort of issues could eat up productive time and could even end up eating up others too. The straight forward solution for this is to use constants instead of using string literals. I recommend to create string constants to set and get values from session.
Here is the prim and proper solution for "Session Name Typo" issue.
public const string AUTOMATION_ID = "AutomationID";
//PageA.aspx
Session[AUTOMATION_ID] = 12;

//PageB.aspx
int Val = (int)Session[AUTOMATION_ID];
  • Session Datatype mismatch - This could happen when a value of type Int64 is set to a session and while accessing the same, the developer might unknowingly casts it to an 'int' (which in Int32 by default), which could lead to overflow bugs. The solution is to use strongly typed Session classes, which we are about to explore.
  • public const string AUTOMATION_ID = "AutomationID";
    //PageA.aspx
    Int64 AutID = 123456789000;
    Session[AUTOMATION_ID] = AutID;
    
    //PageB.aspx
    int Val = (int)Session[AUTOMATION_ID]; //Outputs -1097262584
  • Session Overwriting - This could occur when a developer unknowingly assigns a session name, which is already used by another session for keeping a value of different type. These could be sorted out through strongly typed session class.
  • public const string USER_ID = "UserID";
    //PageA.aspx
    Int64 UserID = 123456789000;
    Session[USER_ID] = UserID ;
    
    //PageB.aspx
    string username = "abcxyz";
    Session[USER_ID] = username; //Here UserID of type In64 is replaced with string.


By now a question might be popping-up in you mind like, why couldn't Microsoft provide a straightforward solution to this problem. Well before waiting for Microsoft to come out with a solution, lets jump into our own customized solution.


So now lets get on to the interesting part of creating a SessionParams class. Here we are going to create a static class named SessionParams for accessing the ASP.NET session in a intuitive object oriented way.


  public static class SessionParams
    {
        #region "Constants"
            private const string SESSION_PREFIX = "SESSION_PARAM_";
            private const string S_USERNAME = SESSION_PREFIX  + "USER_NAME";
            private const string S_AGE = SESSION_PREFIX  + "AGE";
        #endregion

        #region "Private"

        private static T GetParam<T>(string ParamName)
        {
            T Result = default(T);

            if (HttpContext.Current != null &&
                HttpContext.Current.Session != null)
            {
                if (HttpContext.Current.Session[ParamName] != null)
                    Result = (T)HttpContext.Current.Session[ParamName];
            }

            return Result;
        }

        private static void SetParam<T>(string ParamName, T Val)
        {
            if (HttpContext.Current != null &&
                HttpContext.Current.Session != null)
            {
                HttpContext.Current.Session[ParamName] = Val;
            }
        }

        #endregion

        #region "Constructor"
        
        static SessionParams()
        {
            //Place any initialization code here.
        }

        #endregion

        #region "Public Session Params"

        //Sample Session properties  
        public static string UserName
        {
            get { return GetParam<string>(S_USERNAME); }
            set { SetParam(S_USERNAME , value); }
        }

        //Sample Session properties
        public static int Age
        {
            get { return GetParam<int>(S_AGE); }
            set { SetParam(S_AGE , value); }
        }

        #endregion        
    }


What you just saw is a strongly typed session proxy class, which could be just accessed like any other static classes from ASP.NET pages and usercontrols. If you dig into the "SessionParams" class, you could see its a simple session wrapper. 


Now lets dissect the SessionParams class and see, what goes inside into this SessionParams class. The first thing is that, the SessionParams class is logically split to three regions like Constants, Private methods and Public properties.


The Constants region contains the names of session variables. While the Private methods region contains two generic methods namely "GetParam" and "SetParam" of both which receives a generic parameter. These two methods provide the core functionality of retrieving and assigning values to and from session variables; under the hood every public properties for this SessionParams is wrapping around these generic methods. Finally the third region the Public Properties. This is the place where you can access and define new session parameters for accessing, session values from ASP.NET usercontrols and pages.


The SessionParams class we had just discussed is having two sample session variables "Username" and "Age". Here's how to get and set values from the sample session variables.
string NameVal = "AlphaBeta";
int AgeVal = 25;

SessionParams.UserName = NameVal;
SessionParams.Age = AgeVal;

Response.Write(SessionParams.UserName);
Response.Write(SessionParams.Age);

Lets create a new param named "IsRegistered" of type "bool" inside the SessionParams class
  • First of all, you need to create a constant inside the constants region.
private const string S_IS_REGISTERED = SESSION_PREFIX  + "IS_REGISTERED";
  • There after, create a public property named "IsRegistered" of type bool inside region "Public Session Params" like the one below.
public static bool IsRegistered
        {
            get { return GetParam<bool>(S_IS_REGISTERED); }
            set { SetParam(S_IS_REGISTERED , value); }
        }
  • Thats it; now you new property "IsRegistered" is ready for action. Here's how its put into use.
SessionParams.IsRegistered = true;
Response.Write(SessionParams.IsRegistered);

Now we have a strongly typed SessionParams class in place, for interacting with ASP.NET sessions, which is to iron out the problems previously discussed. 


If you happen to encounter any issues with the SessionParams implementation, please let me know.


Monday, April 26, 2010

Impressions of Eyjafjallajokull Volcano

The Eyjafjallajokull volcano in Iceland was in the news headlines these days, crippling down the business and life's of millions. But what ever be the events, there is something pretty for the camera eye to capture on to. Here at Boston.com you can find some find some creative impressions taken from the very heart of the volcanic activity.



Thursday, April 22, 2010

C# Copy Property Values between Types


For a recent project, i came across a quite weird requirement. The requirement was to copy Public Property values in TypeA to TypeB. The criteria was that both the types should have the same property names, otherwise those properties will be skipped. The second criteria was that, it should copy nested types contained in a given source type. 


A word of caution. If you have Enums as properties, then both Enums in TypeA as well as in TypeB should share the same numerical values, even if Enum names are different. One more item is that, nested types should have the default constructor, else you should remove the "new()" generic constraint.


You can use this use the code below, if you come across similar sort of requirements. :)

    public static class Converter
    {
        public static void CopyProperties<T, Q>(T Src, Q Dest)
            where T : new()
            where Q : new()
        {
            foreach (PropertyInfo objSrcPI in Src.GetType().GetProperties())
            {
                PropertyInfo objDestPI = Dest.GetType().GetProperty(objSrcPI.Name);
                Object Val = null;

                if (objDestPI != null)
                {
                    if (objDestPI.PropertyType.BaseType == typeof(Enum))
                    {
                        Val = (int)objSrcPI.GetValue(Src, null);
                        Dest.GetType().GetProperty(objSrcPI.Name).SetValue(Dest, Val, null);
                    }
                    else if (objDestPI.PropertyType == objSrcPI.PropertyType)
                    {
                        Val = objSrcPI.GetValue(Src, null);
                        Dest.GetType().GetProperty(objSrcPI.Name).SetValue(Dest, Val, null);
                    }
                    else if (objDestPI.PropertyType != objSrcPI.PropertyType)
                    {
                        if (!objDestPI.PropertyType.IsValueType &&
                            !objDestPI.PropertyType.IsPrimitive &&
                            objSrcPI.GetValue(Src, null) != null)
                        {
                            Type objDestType = objDestPI.PropertyType;
                            Object objDest = Activator.CreateInstance(objDestType);
                            Val = objSrcPI.GetValue(Src, null);
                            CopyProperties(Val, objDest);
                            Dest.GetType().GetProperty(objSrcPI.Name).SetValue(Dest, objDest, null);
                        }
                    }
                }
            }
        }
    }

Using the CopyProperties procedure

    class A
    {
        public string FirstName { get; set; }
        public int Age { get; set; }
    }

    class B
    {
        public string FirstName { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A objA = new A();
            B objB = new B();

            objA.FirstName = "Alpha";
            objA.Age = 12;

            Converter.CopyProperties(objA,objB);
        }
    }


Google Rolls Out "Governmental Requests" Service

If you wish to get a sneak preview of censorship and filtering requests Google had been receiving from different parts of the world, then read on.


Google had rolled out a new service called "Government Requests", which lists out statistics from different governmental agencies around the world all the way from, requests to pull down a service, removing content from Youtube, Blogger, Orkut; Data Requests etc. However Google itself agrees that the list provided through this service is not a comprehensive one, but they had tried their best possible to get the figures available to public. You can find statistics for most countries except from ones like China, which considers the requests itself as National secrets.


You can visit the service at http://www.google.com/governmentrequests/ 



Tuesday, April 20, 2010

SQL Intellisense

With the launch of SQL Server 2008 Management Studio (SSMS) a pretty sought after feature the "Intellisense" is now a built-in feature shipped with the editor. The feature dramatically improves the productivity by providing a auto complete list of table names after keying in the "FROM" keyword, similarly you will get a list of relevant column names after the "WHERE" clause. I really adore this feature; because most of the time either the table or column names are abbreviated which introduces a lot of typo as you keyin those SQL statements. 

I was glad to see this Intellisense feature and decided to try it out. After downloading the installation took more time than expected, I fired up the Management Studio but to my shock, i couldn't find the Intellisense in action. After going through forums i came to realize that, this feature works only with SQL Server 2008 server and not with down-version systems (like SQLServer 2005, 2000), but unfortunately at the time of this writing i was using SQL Server 2005 server, which doomed my expectations to get a preview of this very sought after feature. 

After a brief search, I came to find similar products offering the same feature; independent of SQL Server version. The first one that caught my attention was Red-Gate's SQLPrompt which provided Intellisense feature for SQL Management Studio regardless of SQL Server version. I was very much impressed by its features after going through its trial version, I really recommend it as a must to have productivity tool for any developer working with databases, but what made be pull back was its quite hefty price tag, for personal use. 

Later i stumbled upon a free product named "Toad for SQLServer", after the installation i was really impressed by what it had to offer. Its packed with features, much more than i expected. I am enumerating the features shipped with this freeware.

  • SQL Intellisense
  • Data Export Wizard
  • Code Snippets
  • Auto Correct for misspelled SQL keywords.
  • SQL Syntax Templates
  • SQL Execution Plan
  • Results Windows - Assists in Grouping, Sorting, Filtering.
  • Moreover this freeware version won't get expired as Toad Oracle Freeware does.






Saturday, April 17, 2010

A Truly Motivational Saga

I had a belief that only a sound financial background and knowledgeable parents could make their children to dream for the skies. But latter going through the biographies of some very eminent self made personalities, I came to realize that nothing is of a barrier from realizing your dream, be it monetary, physical or circumstances. If you have that craving desire and passion, then even failure couldn't stop you from achieving what you had envisioned. The only obstacles, one can see is the lack of focus, interest, willingness and at times even procrastinating the goals. Recently I came across a real life story which made this belief even more firm and I definitely recommend this as a "Must to Read".

In a remote village in Tamilnadu, a boy named Veerapandyan whose determination and passion got himself into, what is called as the steel framework of India, against all the odds. I assume none of us had went through the hardships like the one he had faced, even then he made it to the top overcoming all those baffling hurdles, thus setting himself as an example on how to conquer the unachievable, I believe theres a lot to learn from him for all of us.

I am quoting a striking sentence from the article, which really inspired me and certainly each one of you."

"You will accomplish 100% what you wish When you are firm in your goal."

You can find the complete article here. 



This is another story of a young man, whose had set an example of empowerment through education. You can find the complete article here.



Friday, April 16, 2010

Get yourself reviewed

Its the very instinct of every humanbeing to dream big and high, but what really makes one succeed is the moment when one assess himself/herself and starts to workout in a planned and focussed manner in materializing the dream.

Recently I came to stumble upon a site, that provided a cluster of assessment tests free of cost, if you are interested you can get yourself assessed at http://similarminds.com/, Click on "Personality Tests" link (located on the top left side of the image) and take a test of your choice.