Tuesday, June 3, 2008

Perfect ASP.NET application, Part 5

Benefits of clsStandardPage

Note: You must see previous post to understand what I am talking about here.

Let's talk about our project and what we have already.

First we have clsBrowser:

public class clsBrowser
{
    public string _sFirstName = '';
}

Then we have our clsStandardPage all pages derived from

public class clsStandardPage : System.Web.UI.Page
{
    public clsBrowser _objBs;

    protected override void OnPreInit(EventArgs e)
    {
        //no caching
        Response.CacheControl = "no-cache";
        Response.Expires = -1;
        //Get Browser object
        _objBs = (clsBrowser)Session["browser"];
        if (_objBs == null)
            Session["browser"] = _objBs = new clsBrowser();
        base.OnInit(e);
    }
}

So now it's time to see why we went through all the trouble and did all that. Our customer comes to us and says that he want people to be able to login before seeing content of the web site. So here are our steps. 
Note: I will skip some code that you can see in previous posts.

public class clsBrowser
{
    public int _iUserId = -1;   
//add iUserId for users
    ....
}

public class clsStandardPage : System.Web.UI.Page
{
    public clsBrowser _objBs;
    private bool _bRequiresLogin = false;

    public bool RequiresLogin
    {    
        get {return _bRequiresLogin;}
        set { _bRequiresLogin = value;}
    }
    protected override void OnPreInit(EventArgs e)
    {
            ..............get _objBs.......
   
         //Check if user is not logged in then redirect to login.aspx
            if
( _bRequiresLogin && ( _objBs.iUserId == -1 ) )
                Response.Redirect("~/login.aspx");  
           base.OnInit(e);
    }
}

------Login.aspx--------
<%@ Page RequiresLogin = "false" %>
.....code to do actual login and set our _objBs._iUserId to valid UserId

Note: We added public property RequiresLogin to avoid infinite loop. Our Login.aspx is derived from clsStandardPage and we do not want to redirect from it on itself. 
Note: If we not using separate .cs file we can declaratively set it to RequiresLogin  to false (like i did). Unfortunately if you separate aspx page and .cs file you will not be able to do that. Visual Studio throws a compiler error. (Not sure about VS 2008). In this case you would have to set RequiresLogin to false in constructor. 
Note: You need to set RequiresLogin only on Login.aspx since by default we set it to true.


Another reason to do it that way.... I had a client who came back to me after site was done and said "We want to do bait and switch. Meaning that we let users to see 10 pages of our web site without having him to create an account/login. Then when he sees what we offer he would more easily give us his email address."

Good luck doing that with your standard way.....

I did it with practically 3 lines of code. 

public class clsBrowser
{
    public int _iUserId = -1;   
//add iUserId for users
    public int _iCounter = 0;  
//page view counter
    ....
}

public class clsStandardPage : System.Web.UI.Page
{
    ........
    protected override void OnPreInit(EventArgs e)
    {
            ..............get _objBs.......
   
         //Check if user is not logged in then redirect to login.aspx
            if
( _bRequiresLogin && ( _objBs.iUserId == -1 ) )
            {
                 if( _objBs._iCounter > 10)
                    Response.Redirect("~/login.aspx");  
                else
   
                 _objBs._iCounter ++;
            }
           base.OnInit(e);
    }
}

Note: We only count pages that requires login. And it makes sense. We do not want to make person "pay" (in terms of views) if poor guy refreshed login page 10 times. Or was looking at our "Privacy Policy". Only real content matters.

I hope by now you starting to like the way I do it.....

Continue >>

No comments: