Designing the Interface and More for an Online E-Mail System in ASP.NET 2.0

Picking up from where we left off last time, we're going to start developing the components that we will need for our integrated online email system. We will start with designing the interface, then move on to the data tier.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 9
June 12, 2007
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

A downloadable .rar file is available for this article.

Labor over the Solution

From now on, we are going to explore how to develop each basic component that constitutes an integrated online e-mail system.

Designing the Interface

To enhance the extensibility and flexibility of this system, we've designed two interfaces: IFolder and IMail.

1. IFolder Interface

This interface declares the basic methods associated with folders, such as the method GetFolders for getting information about all mailboxes, the method NewFolder for creating a new mailbox, and so forth. The following Figure 3 gives us the class diagram of the IFolder interface.

Figure 3-the class diagram of the IFolder interface

As is shown in Figure 3, we encapsulate all the basic mailbox operation-related declarations into a single interface, which is a good practice in real life. Moreover, below the IFolder interface, we've defined a Folder class which is derived from the abstract IFolder interface to implement all the methods declared in its parent. Since all the modules are small and basic, and even self-explanatory, we do not explain too much about them here. We'll clarify some of them in the next section and in later use.

2. IMail Interface

Compared to the IFolder interface declared above, this interface is more important, because it encapsulates nearly all the underlying operations relevant to e-mail, i.e. getting and modifying the system profile information, obtaining all the e-mail messages or those from single mailbox, sending e-mail, adding the e-mail sent to the mailbox, adding the e-mail's attachments, moving/deleting e-mail, and fetching the e-mail's attachments. That's 11 function in all. Figure 4 below gives you a more descriptive and clearer approach; it is the class diagram for the IMail interface.

Figure 4-the class diagram for the IMail interface

Seen from the figure, a new class derived from the parent IMail interface, namely Mail, is also defined. Mail is responsible for implementing all the related methods declared in its abstract parent interface. We choose not to talk about it much here, and to let the practical examples later explain everything.

Designing the Data Tier

In fact, alert readers may have sensed that this sample system is composed of a typical three-tier structure: the web pages correspond to the representation tier, the interfaces defined above are associated with the logic tier, and the SQL Server database is related to the data tier. The data access tier (the logic tier) of the whole system mainly lies in two classes: Folder and Mail depicted above, along with an auxiliary class, named WebMailProfile (in fact a struct) to hold the system profile information. And with further digging, you can easily find that the WebMailProfile class is closely connected with two methods (GetWebMailProfile and WebMailProfile) defined in the Mail class. The sketch in Figure 5 gives us a more vivid depiction on the relationships between the modules we'll use:

Figure 5-the sketch shows the relationships between the modules

Here, for brevity, we choose to omit all other methods for there are so many of them (see the downloadable source code for detail). However, I want to single out a representative method, named SaveAsMail of the Mail class, to give the typical implementation of the logic tier above. The following lists the complete source code of the SaveAsMail method:

 

public int SaveAsMail(string sTitle,string sBody,string sFrom,string sTo,

      string sCC,bool bHtmlFormat,int nContain,bool bAttachmentFlag)

  {

    ///open the link to the database

    SqlConnection myConnection = new SqlConnection(

      ConfigurationManager.ConnectionStrings["SQLCONNECTIONSTRING"].ConnectionString);

    SqlCommand myCommand = new SqlCommand("Pr_SaveAsMail",myConnection);

    myCommand.CommandType = CommandType.StoredProcedure;

    ///give the parameters of the stored procedure

    SqlParameter pTitle = new SqlParameter("@Title",SqlDbType.VarChar,200);

    pTitle.Value = sTitle;

    myCommand.Parameters.Add(pTitle);

    SqlParameter pBody = new SqlParameter("@Body",SqlDbType.Text,2147483647);

    pBody.Value = sBody;

    myCommand.Parameters.Add(pBody);

    SqlParameter pFrom = new SqlParameter("@FromAddress",SqlDbType.Text,2147483647);

    pFrom.Value = sFrom;

    myCommand.Parameters.Add(pFrom);

    SqlParameter pTo = new SqlParameter("@ToAddress",SqlDbType.Text,2147483647);

    pTo.Value = sTo;

    myCommand.Parameters.Add(pTo);

    SqlParameter pCC = new SqlParameter("@CCAddress",SqlDbType.Text,2147483647);

    pCC.Value = sCC;

    myCommand.Parameters.Add(pCC);

    SqlParameter pHtmlFormat = new SqlParameter("@HtmlFormat",SqlDbType.Bit,1);

    pHtmlFormat.Value = bHtmlFormat.ToString();

    myCommand.Parameters.Add(pHtmlFormat);

    SqlParameter pContain = new SqlParameter("@Contain",SqlDbType.Int,4);

    pContain.Value = nContain;

    myCommand.Parameters.Add(pContain);

    SqlParameter pAttachmentFlag = new SqlParameter("@AttachmentFlag",SqlDbType.Bit,1);

    pAttachmentFlag.Value = bAttachmentFlag.ToString();

    myCommand.Parameters.Add(pAttachmentFlag);

    SqlParameter pMailID = new SqlParameter("@MailID",SqlDbType.Int,4);

    pMailID.Direction = ParameterDirection.ReturnValue;

    myCommand.Parameters.Add(pMailID);

    ///define the returned data

    int nResult = -1;

    try

    {

      ///open the link

      myConnection.Open();

      ///execute the SQL clause

      nResult = myCommand.ExecuteNonQuery();

    }

    catch(SqlException ex)

    {

      ///throw exception

      throw new Exception(ex.Message,ex);

    }

    finally

    { ///close the link

      myConnection.Close();

    }

    ///return nResult

    return(int)myCommand.Parameters[8].Value;

  }

 

In this method, the e-mail that has just been sent out is to be saved in the mailbox. First of all, we create and open a link to the SQL Server database (the linking string is defined in the web.config file). Second, we get ready to invoke the Pr_SaveAsMail stored procedure defined in the previous Database Design section by populating the parameters of the ASP.NET built-in objects SqlCommand and SqlParameter. Third, we execute the SQL clause to perform the real task within a safer try block. And finally, we return some according the method definition. It's a seemingly long, but indeed a typical database operation in the logic tier, isn't it?

So much for the lower development! Starting with the next section, we'll examine the presentation tier design.

Check Your Mailbox List

To see the mailbox list, we use three pages: Main.aspx, LeftTree.aspx, and MailDesktop.aspx, respectively, which concretely contain the following functions:

  • Display the mailboxes in tree-like form;
  • Display the mailboxes in table-like form;
  • Provide the hyperlink to rename a mailbox;
  • Provide the hyperlink to check the e-mails in a mailbox;
  • Provide the hyperlink to create a new mailbox; and
  • Delete a mailbox.

As the main page of the whole online e-mail system, the Main.aspx page is composed of two HTML frame elements (i.e. <frame>) named Left (used for loading the LeftTree.aspx page) and Desktop (used for loading the  MailDesktop.aspx page) respectively. The following gives you the crucial HTML code related to this:

 

<frameset id="Frame" cols="180,*" rows="*" border="0" framespacing="0">

  <frame name="Left" src="LeftTree.aspx" scrolling="no" frameborder="0" noresize="true">

  <frame name="Desktop" src="MailDesktop.aspx" scrolling="auto" frameborder="0">

</frameset>

 

And Figure 6 illustrates the run-time snapshot of the main.aspx page (called by the index.aspx page) in Microsoft IE:

Figure 6-the run-time snapshot of the main page of the online e-mail system

The LeftTree.aspx page is responsible for showing the mailboxes in a TreeView control corresponding to the left part in Figure 6. When initialized, the Page_Load function invokes a helper function named InitOperationTree to bind the data to the OperationView control (i.e. the TreeView control in Figure 6):

 

protected void Page_Load(object sender, EventArgs e) {

  if(!Page.IsPostBack)

  { ///initialize the operation tree

    InitOperationTree();

  }

}

private void InitOperationTree()

{ ///obtain data

  IFolder folder = new Folder();

  SqlDataReader dr = folder.GetFolders();

  ///fine the mail folder node

  TreeNode mailFolderNode = OperationView.FindNode("-1/0");

  if(mailFolderNode == null) { return; }

  ///add the mail folder

  while(dr.Read())

  { ///create the node

    TreeNode node = new TreeNode();

    node.NavigateUrl = "~/ViewMail.aspx?FolderID=" + dr["FolderID"].ToString();

    node.Target = "Desktop";

    node.Text = dr["Name"].ToString();

    node.Value = dr["FolderID"].ToString();

    mailFolderNode.ChildNodes.Add(node);

  }

  dr.Close();

}

 

In the helper function InitOperationTree above, we first call the GetFolders method of the Folder class to obtain the required dataset, then find the mail folder node, and finally add the folder information from the dataset onto the TreeView control through a typical while loop. Note that when we create the tree node, we set up the hyperlink to the related folder in the ViewMail.aspx page.

With regard to viewing the mail list, this is accomplished through the MailDesktop.aspx page (which corresponds to the right part of Figure 6) whose design-time snapshot in shown in Figure 7 below.

Figure 7-the design-time snapshot of page MailDesktop.aspx

This page is rather simple, with merely a GridView (named FolderView, used to display the mailboxes) and a Button (named NewFolderBtn, used to add new mailbox hyperlink) on it. When the MailDesktop.aspx page initializes, we bind data to the FolderView control (i.e. show the information in the specified mailbox). Since this code is quite similar to that of the LeftTree.aspx page, we omit it. When you click on the NewFolderBtn button, you will be directed to another page, namely NewFolder.aspx, to create the required mailbox hyperlink.

 

Response.Redirect("~/NewFolder.aspx");

 

Check the E-mails in Your Mailbox

Now, let's turn our attention to how to view the e-mails in the selected mailbox, which is done on the ViewMail.aspx page (figure 8 shows the design-time interface).

Figure 8-the design-time snapshot of the ViewMail.aspx page

Here, we enumerate the functions of the controls on this page as follows:

  • GridView MailView -- to show the e-mails in the selected mailbox;
  • DropDownList FolderList -- to show the mailboxes/folders to which the selected e-mails are moved;
  • Button DeleteBtn -- to delete the mails checked out (i.e. selected);
  • Button MoveBtn - -to move the selected e-mails to the mailbox currently selected in control DropDownList.

As discussed in the MailDesktop.aspx page, the main task is finished when the page is loaded. When the ViewMail.aspx page is initialized, we need to perform the following functions:

1. Obtain the value of the nFolderID parameter;

2. Display the e-mails within the current mailbox or folder in the MailView control, which is accomplished by calling the helper function BindMailData which in turn invokes the GetMailsByFloder method of the Mail class to get the details (such as mail topic, sending time, sender, and so forth) of all the e-mails in the current mailbox/folder using the nFolderID parameter;

3. Exhibit the information about the mailbox/folder in the FolderList control,  which is done with the helper function BindFolderData.

 

int nFolderID = -1;

protected string AliasName = "AliasName";

protected string Email = "Email";

protected void Page_Load(object sender,EventArgs e)

{

  ///get the value of parameter nFolderID

  if(Request.Params["FolderID"] != null)

  {

    if(Int32.TryParse(Request.Params["FolderID"].ToString(),out nFolderID) == false)

    { return;}

  }

  if(!Page.IsPostBack){

    if(nFolderID > -1)

    {

      BindMailData(nFolderID);

      BindFolderData();

    }

  }

  DeleteBtn.Attributes.Add("onclick","return confirm('Are you sure to delete the selected files?');");

}

private void BindFolderData()

{ ///get data

  IFolder folder = new Folder();

  SqlDataReader dr = folder.GetFolders();

  ///bind data

  FolderList.DataSource = dr;

  FolderList.DataTextField = "Name";

  FolderList.DataValueField = "FolderID";

  FolderList.DataBind();

  dr.Close();

  MoveBtn.Enabled = FolderList.Items.Count > 0 ? true : false;

}

private void BindMailData(int nFolderID)

{ ///get data

  IMail mail = new Mail();

  SqlDataReader dr = mail.GetMailsByFloder(nFolderID);

  ///bind data

  MailView.DataSource = dr;

  MailView.DataBind();

  dr.Close();

  DeleteBtn.Enabled = MailView.Rows.Count > 0 ? true : false;

}

 

Indeed, there is nothing more to be interpreted in the above code, so let's continue the long journey.

Creating Folders

Here comes the NewFolder.aspx page on which we are to accomplish the task of creating folders. To begin, let's look at its page layout, as shown in Figure 9.

Figure 9-the design-time view of page NewFolder.aspx

Yes, it's a simple but typical interface structure with several common controls on the page! So let's also enumerate their functions:

  • Name Textbox -- for letting the user enter the name of the folder;
  • RequiredFieldValidator rfN -- for checking whether the folder name is empty;
  • OK button (ID being NewBtn) -- for creating a new folder.
  • Return button (ID being ReturnBtn) -- for navigating back to the MailDesktop.aspx page.

Clicking the OK button will trigger the NewBtn_Click (object sender, EventArgs e) event which will create the specified new folder.

 

protected void NewBtn_Click(object sender,EventArgs e) {

  try

  { ///define an object

    IFolder folder = new Folder();

    ///execute the corresponding database operation

    folder.NewFolder(Name.Text.Trim());

    Response.Write("<script>alert('" + "Creating the folder successfully, safekeep your data!" + "');</script>");

  }

  catch(Exception ex)

  { ///jump to the page dealing with exception handling

    Response.Redirect("ErrorPage.aspx?ErrorMsg=" + ex.Message.Replace("<br>","").Replace("n","")

      + "&ErrorUrl=" + Request.Url.ToString().Replace("<br>","").Replace("n",""));

  }

}

 

Inside this event, we call the helper function named NewFolder to add the newly-created folder into the underlying database. When clicking the Return button,  we are navigated back to the MailDesktop.aspx page.

Please check back tomorrow for the conclusion to this article.

blog comments powered by Disqus
ASP.NET ARTICLES

- Implementing ASP.NET 4.0 Page.MetaDescriptio...
- ASP.Net Development Tips
- Intro to Sessions in ASP.Net
- Google Maps API Introduction in ASP.NET usin...
- Creating an ASP.NET 3.5 Gridview Image Galle...
- Encrypt QueryString in ASP.NET 3.5 using VB....
- ASP.NET 3.5 Drop Down List Controls
- Connect to Access Database with ASP.Net
- Secure Audio Streaming with ASP.Net and Flash
- Dynamic Sitemap and Navigation in ASP.Net
- Implement Gzip and Deflate Compression in AS...
- Run ASP.Net in Ubuntu with Apache
- ASP.Net Mono Website Contact Forms
- ASP.Net URL Rewriting Methods
- Murach`s ASP.NET 4 Web Programming with C# 2...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 4 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials