Before I start, I'm going to make a confession. When it comes to ASP.NET, I've probably made every single bad mistake that someone can make. And although the code worked, I look back at some of the things I did in the past and wish I could XCOPY right over it and purge any trace of it from Source Safe. But more than anything else, I wrote a lot of inefficient code and wrote the same stuff over and over again - I guess I thought I was still in ASP land. Anyway, let me walk you through a few things that can make life a lot easier for you.
The first thing I think I really goofed up bad was not realizing how to implement Session State within my classes. What I mean was, I would create a regular class, with all of the get/set accessors like you normally would, and use the class variables to set session variables. Why? Well, because you couldn't use Session state within your classes - or so I thought.
The next thing I did was hard code my session variable names. Not a real big issue per se, but I wasted a lot of time flipping back and forth between pages to see exactly how I named one variable so I could use it again.
The third thing I did wrong was misuse inheritance. Too often I ended up writing the code that did almost the exact same stuff as the base class and instead of redesigning my base classes correctly, I just trucked on ahead with the derived classes.
So let's look at a few ways to deal with some of these problems. First, it's a good idea to not only group your projects in a logical order within a solution, but organize your folder structure as well. Now, people can argue for hours on end how to best organize your solution and project - I won't touch that issue. What matters is that you figure out what works for you and BE CONSISTENT about it. In my experience, I've found that no matter how complex, goofy, bizarre, unintuitive or whatever you organize things - as long as you are very consistent about it, it won't be that big of an impediment because you can count on certain things being true all of the time. So for this project, which doesn't have any real logic in it - I just created one project and three folders underneath it - BasePages, Constants and UIPages:
Now in a real project, things get much more complex, so for instance, I'd normally have a folder for all of my style sheets, XSLT transforms, images. Then I'd group things into logical areas like UI, Administration etc. Another common one is all of the javascript associated with a given area, like Menus. In another project I'd have my Business Interfaces, then one with my Business Objects, DALC Interfaces, DALC Objects, Custom Controls etc.
Ok, let's get down to business. If you add a simple class in your project and try to reference a Session variable, it won't compile. This actually makes sense right? After all, how does a DALC class that may run in multiple contexts, know that it is being used by an ASP.NET Application or Web Service and then figure it what Session is? It can't. However, by adding a class to your project that Inherits from System.Web.UI.Page, you know have a fully functioning web page - although if you added it as a class instead of a web form, you won't have visual support for it. Since we're not grabbing UI elements from the base page, this is actually a good thing. Now, the key here is to use the Session Variables in lieu of the private module level variables you normally use with your get/set accessors. Understand that the world is your's here. If you want to run a Crypto routine here - have at it. If you don't want to use session variables, fine (although if you are sharing these properties among descendants than you are defeating some of the purpose). A very simple implementation is shown below:
using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using KDN.Samples.Constants; namespace KDN.Samples.BasePages { /// <summary> /// Summary description for KDNBasePage. /// public class KDNBasePage : System.Web.UI.Page { public KDNBasePage(){} #region Public Properties public System.String UserName { get { return Session[Constants.UIConstants.UserInfo.UserName]; } set { Session[Constants.UIConstants.UserInfo.UserName] = value; } } public System.String EncryptedPassword { get { return Session[Constants.UIConstants.UserInfo.EncryptedPassword]; } set { Session[Constants.UIConstants.UserInfo.EncryptedPassword] = value; } } #endregion } } |
| public class WebForm1 : KDN.Samples.BasePages.KDNBasePage { protected System.Web.UI.WebControls.TextBox tbUserName; protected System.Web.UI.WebControls.TextBox tbPassword; private void Page_Load(object sender, System.EventArgs e) { tbUserName.Text= base.UserName; tbPassword.Text = base.EncryptedPassword; } } |
| namespace KDN.Samples.Constants { /// <summary> /// Summary description for UIConstants. /// public class UIConstants { public UIConstants(){//Read values from web.config or perform //typical initialization functionality } public class UserInfo { public const String UserName = "userName"; public const String EncryptedPassword = "password"; public const String DomainId = "domainId"; public const String SessionStart = "sessionStart"; } } } |