(c) 2003 Visual Studio Magazine 
Fawcette Technical Publications

C#	Build a Generic User Object
Listing 1	 This code creates the User object that the server control passes to the calling ASP.NET page upon a successful login. You can include any pertinent information in this class, such as roles the user belongs to or groups that contain the user.

using System;

namespace SampleUser
{
	public class User
	{
		private string _username = "";
		private string _email = "";
		private int _userid = 0;

		public int UserID
		{
			get
			{
				return _userid;
			}
			set
			{
				_userid = value;
			}
		}

		public string UserName
		{
			get
			{
				return _username;
			}
			set
			{
				_username = value;
			}
		}

		public string Email
		{
			get
			{
				return _email;
			}
			set
			{
				_email = value;
			}
		}
	}
}


C#	Implement a Login Server Control
Listing A	The LoginForm class inherits from the Control object and implements the INamingContainer interface. It overrides CreateChildControls, which you use to render the form's elements. You define two EventHandlers-Success and Failure-to signal a successful login and a failed login attempt, respectively.

using System; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.ComponentModel; 
using SampleUser;

namespace LoginControl
{
[ParseChildren(true)]  
	public class LoginForm : Control, 
		INamingContainer  
	{
		private User _retUser;
		private string _applicationID;

		public string Application
		{
			set
			{
				_applicationID = value;
			}
		}

		public User theUser
		{
			get 
			{
				return _retUser;
			}
		}

		// This exposes our events to the caller
		// so that the caller can define an 
		// "OnSuccess" event
		public event EventHandler Success;
		protected virtual void 
			OnSuccess(EventArgs e) 
		{     
			if (Success != null) 
			{
				Success(this, e);
			}  
		}

		public event EventHandler Failure;
		protected virtual void 
			OnFailure(EventArgs e) 
		{     
			if (Failure != null) 
			{
				Failure(this, e);
			}  
		}


		// Controls  
		Table table;  
		Label lblUsername;  
		Label lblPassword;  
		Label lblNewPassword;
		Label lblConfirmPassword;
		TextBox txtUserName;  
		TextBox txtPassword;  
		TextBox txtNewPassword;
		TextBox txtConfirmPassword;
		Button btnLogIn;  
		Button btnChangePWD;  
		Button btnCancel;  
		Button btnSavePWD;

		protected override void 
			CreateChildControls()  
		{  
			Controls.Clear();  

			table = new Table();  
			TableRow tr = new TableRow();  
			TableCell td;  

			td = new TableCell();  
			td.Font.Bold = true;
			lblUsername = new Label();  
			lblUsername.Text = "User ID:";  
			td.Controls.Add(lblUsername);  
			tr.Controls.Add(td);  
         
			td = new TableCell();  
			txtUserName = new TextBox();  
			td.Controls.Add(txtUserName);  
			tr.Controls.Add(td);  
     
			table.Controls.Add(tr);  

			tr = new TableRow();  

			td = new TableCell();  
			td.Font.Bold = true;
			lblPassword = new Label();  

			if (ViewState["ChangePWD"] == null)
				ViewState["ChangePWD"] = false;

			if (!(bool)ViewState["ChangePWD"])
				lblPassword.Text = "Password:";  
			else
				lblPassword.Text = 
					"Current Password:";

			td.Controls.Add(lblPassword);  
			tr.Controls.Add(td);  
         
			td = new TableCell();  
			txtPassword = new TextBox();  
			txtPassword.TextMode = 
				TextBoxMode.Password;  
			td.Controls.Add(txtPassword);  
			tr.Controls.Add(td);  

			table.Controls.Add(tr);  

			if ((bool)ViewState["ChangePWD"])
			{
				tr = new TableRow();  

				td = new TableCell();  
				td.Font.Bold = true;
				lblNewPassword = new Label();  
				lblNewPassword.Text = 
					"New Password:";  
				td.Controls.Add(lblNewPassword);  
				tr.Controls.Add(td);  

				td = new TableCell();  
				txtNewPassword = new TextBox();  
				txtNewPassword.TextMode = 
					TextBoxMode.Password;  
				td.Controls.Add(txtNewPassword);  
				tr.Controls.Add(td);  

				table.Controls.Add(tr);  

				tr = new TableRow();  

				td = new TableCell();  
				td.Font.Bold = true;
				lblConfirmPassword = new Label();  
				lblConfirmPassword.Text = 
					"Confirm Password:";  
				td.Controls.Add(lblConfirmPassword);  
				tr.Controls.Add(td);  

				td = new TableCell();  
				txtConfirmPassword = new TextBox();  
				txtConfirmPassword.TextMode = 
					TextBoxMode.Password;  
				td.Controls.Add(txtConfirmPassword);  
				tr.Controls.Add(td);  

				table.Controls.Add(tr);  

			}
			
			tr = new TableRow();  
			td = new TableCell();  
			td.HorizontalAlign = 
				HorizontalAlign.Center;
			td.ColumnSpan = 2;  
			
			if ((bool)ViewState["ChangePWD"])
			{
				btnSavePWD = new Button();  
				btnSavePWD.Text = "Save Password";  
				btnSavePWD.Click += new 
					EventHandler(SavePassword);  
				td.Controls.Add(btnSavePWD);  
				btnCancel = new Button();  
				btnCancel.Text = "Cancel";  
				btnCancel.Click += new 
					EventHandler(CancelPassword);  
				td.Controls.Add(btnCancel);  
			}
			else
			{
				btnLogIn = new Button();  
				btnLogIn.Text = "Login";  
				btnLogIn.Click += new 
					EventHandler(VerifyUser);  
				td.Controls.Add(btnLogIn);  
				btnChangePWD = new Button();  
				btnChangePWD.Text = 
					"Change Password";  
				btnChangePWD.Click += new 
					EventHandler(ChangePassword);  
				td.Controls.Add(btnChangePWD);  

			}
						
			tr.Controls.Add(td);  
			table.Controls.Add(tr);  
     
	if (ViewState["Message"] != null && 
			ViewState["Message"].ToString() != "")
			{
				tr = new TableRow();  
				td = new TableCell();  
				td.HorizontalAlign = 
					HorizontalAlign.Center;
				td.ColumnSpan = 2;  
				td.Text = 
					ViewState["Message"].ToString();
				tr.Controls.Add(td);  
				table.Controls.Add(tr);  

				ViewState["Message"] = "";
			}

			Controls.Add(table);  
		}  

		public void ChangePassword(object sender, 
			EventArgs e)  
		{ 
			ViewState["ChangePWD"] = true;
			CreateChildControls();
		}

		public void SavePassword(object sender, 
			EventArgs e)  
		{  
			// When applied to a database, put logic 
			// to change password here.
		}

		public void CancelPassword(object sender, 
			EventArgs e)  
		{  
			ViewState["ChangePWD"] = false;
			CreateChildControls();
		}

		public void VerifyUser(object sender, 
			EventArgs e)  
		{  
			// Here, you would put database calls to 
			// verify a user, the code below is for 
			// sample purposes.

			_retUser = new User();

			if (_applicationID == "1")
			{
				if (txtUserName.Text == 
					"App1User" && txtPassword.Text == 
					"Password1")
				{
					_retUser.UserID = 1;
					_retUser.UserName = "App1User";
					_retUser.Email = 
						"App1User@noemail.com";

					Success(sender, e);
				}
				else
					Failure(sender, e);
			}	
			else if (_applicationID == "2")
			{
				if (txtUserName.Text == 
						"App1User" && txtPassword.Text 
						== "Password1")
				{
					_retUser.UserID = 1;
					_retUser.UserName = "App1User";
					_retUser.Email = 
						"App1User@noemail.com";

					Success(sender, e);
				}
				else
					Failure(sender, e);
			}
 
		}  

		// Public properties  

		[Bindable(true),  
		Category("Appearance"),  
		DefaultValue("User ID:")]  
		public string UserIDLabel  
		{  
			get  
			{  
				EnsureChildControls();  
				return lblUsername.Text;  
			}  
			set  
			{  
				EnsureChildControls();  
				lblUsername.Text = value;  
			}  
		}  

		[Bindable(true),  
		Category("Appearance"),  
		DefaultValue("Password:")]  
		public string PasswordLabel  
		{  
			get  
			{  
				EnsureChildControls();  
				return lblPassword.Text;  
			}  
			set  
			{  
				EnsureChildControls();  
				lblPassword.Text = value;  
			}  
		}  

		[Bindable(true),  
		Category("Appearance"),  
		DefaultValue("Login")]  
		public string ButtonText  
		{  
			get  
			{  
				EnsureChildControls();  
				return btnLogIn.Text;  
			}  
			set  
			{  
				EnsureChildControls();  
				btnLogIn.Text = value;  
			}  
		} 
	}
}




ASP.NET	Call the Server Control
Listing 2	The ASP.NET page that calls the server control must register the control and then declare it. It also must contain two event handlers that correspond to OnSuccess (handled by MySuccess) and OnFailure (handled by MyFailure).  MySuccess accesses the populated user object that the LoginForm contains.

<%@ Page language="c#" Codebehind="Login.aspx.cs" 
	<%@ Register TagPrefix="ctlLogin" 
	Namespace="LoginControl" 
	Assembly="Article_LoginControl" %>
AutoEventWireup="false" 
	Inherits="ArticleCallingApp.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
	<HEAD>
		<title>Login</title>
		<meta name="GENERATOR" Content="Microsoft 
			Visual Studio 7.0">
		<meta name="CODE_LANGUAGE" Content="C#">
		<meta name="vs_defaultClientScript" 
			content="JavaScript">
		<meta name=
			"vs_targetSchema" content=
			"http://schemas.microsoft.com/
			intellisense/ie5">
	</HEAD>
	<body MS_POSITIONING="GridLayout">
		<form id="Form1" method="post" 
			runat="server">
			<ctlLogin:loginform id="Lform" 
				runat="server" 
Application="1" OnSuccess="MySuccess" 
	OnFailure="MyFailure"></ctlLogin:loginform>
			<asp:Label id="lblMessage" style=
				"Z-INDEX: 101; LEFT: 17px; POSITION: 
				absolute; TOP: 109px" runat="server" 
				Width="342px" 
				Height="78px"></asp:Label></TD>
		</form>
	</body>
</HTML>

Code:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using SampleUser;
using LoginControl;

namespace ArticleCallingApp
{
	public class WebForm1 : System.Web.UI.Page
	{
		protected System.Web.UI.WebControls.Label 
			lblMessage;
		protected LoginControl.LoginForm Lform;
	
		protected void MySuccess(object sender, 
			EventArgs e)
		{
			SampleUser.User myUser = Lform.appUser;
			
			lblMessage.Text = "User ID : " + 
				myUser.UserID;
		}

		protected void MyFailure(object sender, 
			EventArgs e)
		{
			lblMessage.Text = "Login Failed.  Please 
				try again.";
		}

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			InitializeComponent();
			base.OnInit(e);
		}
		
		private void InitializeComponent()
		{    
			this.Load += new 
				System.EventHandler(this.Page_Load);
		}
		#endregion
	}
}



