Suppose we are developing an application for teachers in a school that tracks which of its students have registered for a certain event in the school. A teacher should be able to add a student to the list of those participating in the event, remove a student, and so on.
For this functionality, we will create a StudentList class that is a collection of Student types. A teacher can add and remove any student from the StudentList collection. Storing this class in a Profile object means that the student list will be available automatically every time the teacher logs in to his or her account.
Listing 2 shows a Profile configuration section that defines a Profile property whose type refers to a class of type StudentList. In addition, we see a new serializeAs attribute that is used to persist the StudentList class using binary serialization.
Listing 2. Profile Configuration Section with a Custom Object
<anonymousIdentification enabled="true"/>
<Profile enabled="true">
<properties>
<add name="StudentList" type="StudentList" allowAnonymous="true" serializeAs="Binary" />
</properties>
</Profile>
Listing 3 shows the code for the implementation of the StudentList class. This class has methods to add and remove student records from the list. It also contains a property that represents the number of students’ records in the student list.
Listing 3. StudentList
using System;
using System.Collections;
[Serializable]
public class StudentList : IEnumerable
{
private Hashtable _StudentRecords = new Hashtable();
//Return Student Records
public Hashtable StudentRecords
{
get { return _StudentRecords; }
}
// Return the number of student records in the student list
public int AllRecords
{
get
{
int Count = 0;
foreach (StudentRecord sr in _StudentRecords.Values)
{
Count++;
}
return Count;
}
}
// Add a new Student Record to the student list
public bool AddRecord(int StudentId, StudentRecord sr)
{
StudentRecord _SR = (StudentRecord)_StudentRecords[StudentId];
if (_SR == null)
{
_StudentRecords.Add(StudentId, sr);
return true;
}
// Student record is already in the list
return false;
}
// Remove a student record from the list if found
public bool RemoveRecord(int StudentId)
{
StudentRecord _SR = (StudentRecord)_StudentRecords[StudentId];
if (_SR == null)
{
// The record to be deleted is not in the list.
return false;
}
// Student record is in the list
_StudentRecords.Remove(StudentId);
return true;
}
// Allow to use foreach by implementing the IEnumerable Interface.
public IEnumerator GetEnumerator()
{
for ( int i = 1; i <= _StudentRecords.Count; i++ )
yield return _StudentRecords[i];
}
}
As we have seen in the above listing, we have used a custom object called StudentRecord which represents one student record. Listing 4 below presents the implementation of that custom object.
Listing 3. StudentRecord
using System;
using System.Data;
using System.Configuration;
[Serializable]
public class StudentRecord
{
#region Private Fields
private int _StudentId;
private string _FirstName;
private string _LastName;
#endregion
#region Constructor
public StudentRecord(int StudentId, string FirstName, string LastName)
{
_StudentId = StudentId;
_FirstName = FirstName;
_LastName = LastName;
}
#endregion
#region Properties
public int StudentId
{
get { return _StudentId; }
}
public string FirstName
{
get { return _FirstName; }
}
public string LastName
{
get { return _LastName; }
}
#endregion
}
The above two classes should be placed in the App_Code directory, which is a system directory that contains all custom objects created in the Web application. This directory will be compiled into a single DLL at runtime and all the custom objects placed inside it will be accessible to all the ASP.NET pages in the application.
Also notice that each class has an attribute of Serializable. This attribute should be set because both objects must be serialized in order to be stored in a Profile object.
Listing 5 presents the page that allows each teacher to add a new student record to the StudentList (See Figure 1).
Figure 1. Add Record
Listing 5. AddRecord.aspx
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class AddRecord : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
PlaceHolder1.Visible = false;
}
protected void Button1_Click(object sender, EventArgs e)
{
// New instance of StudentRecord
StudentRecord sr = null;
// Studen record
int _Id;
bool TempId = int.TryParse( TextBox3.Text, out _Id );
if (TempId &&
!string.IsNullOrEmpty(TextBox1.Text) &&
!string.IsNullOrEmpty(TextBox2.Text)
}
sr = new StudentRecord(_Id, TextBox1.Text, TextBox2.Text);
else
// If one of the field are wrong we return
// and don’t insert the record
return;
// Initialize the list if empty
if (Profile.StudentList == null)
Profile.StudentList = new StudentList();
// Show Place holder
PlaceHolder1.Visible = true;
// Add student record to list
if (Profile.StudentList.AddRecord(_Id, sr))
{
// Display the Profile proeprties
string TextToDisplay = "Student with Id <b>" + _Id + "</b> is added to the list <br />";
PlaceHolder1.Controls.Add(new LiteralControl(TextToDisplay));
PlaceHolder1.Controls.Add(new LiteralControl("<hr /><br />"));
}
else
PlaceHolder1.Controls.Add(new LiteralControl("Student is already in the list"));
}
}
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AddRecord.aspx.cs" Inherits="AddRecord" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"<a href="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd</a>">
<html xmlns="<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>" >
<head runat="server">
<title>Add Record Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<div>
<h2>
Teacher Administration Area</h2>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
<br />
<br />
Student Id :
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox><br />
<br />
First Name :
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<p>
Last Name :
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox></p>
<p>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Add User" /></p>
</div>
</div>
</form>
</body>
</html>
Listing 6 presents the page that allows each teacher to remove a student record from the StudentList (See Figure 2).
Figure 2. Remove Record
Listing 6. RemoveRecord.aspx
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class RemoveRecord : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
PlaceHolder1.Visible = false;
}
protected void Button1_Click(object sender, EventArgs e)
{
// Studen record
int _Id;
bool TempId = int.TryParse(TextBox3.Text, out _Id);
// Show Palce holder
PlaceHolder1.Visible = true;
if (TempId)
{
// Add student record to list
if (Profile.StudentList.RemoveRecord(_Id))
{
// Display the Profile proeprties
string TextToDisplay = "Student with Id <b>" + _Id + "</b> is removed from the list <br />";
PlaceHolder1.Controls.Add(new LiteralControl(TextToDisplay));
PlaceHolder1.Controls.Add(new LiteralControl("<hr /><br />"));
}
else
PlaceHolder1.Controls.Add(new LiteralControl("Student is not found in the list"));
}
else
PlaceHolder1.Controls.Add(new LiteralControl("Student Id is not a valid Id"));
}
}
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="RemoveRecord.aspx.cs" Inherits="RemoveRecord" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"<a href="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd</a>">
<html xmlns="<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>" >
<head runat="server">
<title>Remove Record Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<div>
<div>
<h2>
Teacher Administration Area - Remove Record</h2>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
<br />
<br />
Student Id :
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox><br />
<p>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Remove Student" /></p>
</div>
</div>
</div>
</form>
</body>
</html>
Finally, the page in Listing 7 below displays a list of all students’ records that have been previously added using the AddRecord.aspx page (see Figure 1). We have looped through all the student records stored within the StudentList property of the Profile object and displayed them on the page.
Figure 3. Display StudentList records
Listing 7. Displaying StudentList records
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class DisplayRecords : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
PlaceHolder1.Controls.Add(new LiteralControl("There are " + Profile.StudentList.AllRecords + " student(s) in the list: <br /><br/>"));
foreach (StudentRecord sr in Profile.StudentList)
{
PlaceHolder1.Controls.Add(new LiteralControl("Student Id : " + sr.StudentId + "<br />"));
PlaceHolder1.Controls.Add(new LiteralControl("First Name : " + sr.FirstName + "<br />"));
PlaceHolder1.Controls.Add(new LiteralControl("Last Name : " + sr.LastName + "<br /><hr /><br/>"));
}
}
}
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DisplayRecords.aspx.cs" Inherits="DisplayRecords" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"<a href="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd</a>">
<html xmlns="<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>" >
<head runat="server">
<title>Display All Student Records</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h2>
Teacher Administration Area - Display Records</h2>
<p>
</p>
<p>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</p>
</div>
</form>
</body>
</html>